c语言 - Posix 调用"读取"不会读取整个文件



在使用文件编程时,我偶然发现了C库"fread"函数和POSIX调用"read"之间的一些奇怪差异;"read"只读取文件的几个字节,而"fread"读取整个文件。此代码仅读取 1024 + 331 字节,然后"read"返回 0:

char buf[1024];
int id = open("file.ext", 0);
int len;
while((len = read(id, buf, 1024)) > 0)
    println(len);

虽然此代码按预期读取整个文件,但大约 11kb:

char buf[1024];
FILE* fp = fopen("file.ext", "rb");
int len;
while((len = fread(buf, 1, 1024, fp)) > 0)
    println(len);

你能说出为什么"read"不会读取整个文件吗?

编辑2:很抱歉,我正在使用带有MinGW的Windows,并读取二进制文件

编辑:一个完整的例子:

#include <io.h>
#include <stdio.h>
int main() {
    char buf[1024];
    int len;
    // loop 1
    int id = open("file.ext", 0);
    while((len = read(id, buf, 1024)) > 0) {
        printf("%dn", len);
    }
    close(id);
    println("--------");
    // loop 2
    FILE* fp = fopen("file.ext", "rb");
    while((len = fread(buf, 1, 1024, fp)) > 0) {
        printf("%dn", len);
    }
    fclose(fp);
    while(1) {}
    return 0;
}

输出:

1024
331
--------
1024
1024
1024
1024
1024
1024
1024
1024
1024
1024
981

您第一次在文本模式下打开文件,第二次在二进制模式下打开文件。您需要在二进制模式下两次打开它。如果它不在二进制模式下,第一个 control-z(十六进制值 1A)表示"文件结束"。

添加以下内容包括(删除<io.h>):

#include <unistd.h>
#include <fcntl.h>

调用打开方式如下:

int id = open("spiderman.torrent", O_RDONLY|O_BINARY);

下面是 control-z 结束文件的示例:

#include <stdio.h>
void writeit() {
  FILE *f = fopen("test.txt", "wb");
  fprintf(f, "hello worldrn");
  fputc(0x1A, f);
  fprintf(f, "goodbye universern");
  fclose(f);
}
void readit() {
  int c;
  FILE *f = fopen("test.txt", "r");
  while ((c = fgetc(f)) != EOF)
    putchar(c);
  fclose(f);
}
int main() {
  writeit();
  readit();
  return 0;
}

以上只印"你好世界",不印"再见宇宙"。

问题已更新...

fread()循环很奇怪:

while ((len = fread(buf, 1, 1024, fp) > 0))
    println(len);

看看括号——它们相当于:

while ((len =   (fread(buf, 1, 1024, fp) > 0)   ))

现在,fread()将返回读取的字节数,但分配给len的值将是 01 ,因此从println()打印应重复1几次,然后停止。

您是实际代码,还是在创建问题时输入错误?

编译并运行这个程序(我称之为rdrd.c编译):

#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define FILENAME "file.ext"
static void println(int val)
{
    printf("%dn", val);
}
int main(void)
{
    char buf[1024];
    int len;
    int id = open(FILENAME, 0);
    while ((len = read(id, buf, 1024)) > 0)
        println(len);
    close(id);
    FILE *fp = fopen(FILENAME, "rb");
    while ((len = fread(buf, 1, 1024, fp)) > 0)
        println(len);
    fclose(fp);
    struct stat sb;
    stat(FILENAME, &sb);
    printf("Size: %dn", (int)sb.st_size);
    return 0;
}

示例输出:

$ ls -l file.ext
-rw-r--r--  1 jleffler  staff  7305 Apr  6 08:08 file.ext
$ ./rd
1024
1024
1024
1024
1024
1024
1024
137
1024
1024
1024
1024
1024
1024
1024
137
Size: 7305
$

相关内容

  • 没有找到相关文章