代码之家  ›  专栏  ›  技术社区  ›  David Holm

fread/fwrite将大小和计数作为参数的理由是什么?

  •  81
  • David Holm  · 技术社区  · 17 年前

    我们在工作中讨论了原因 fwrite() 获取每个成员的大小,然后计数并返回读/写的成员数,而不仅仅是获取缓冲区和大小。我们能想到的唯一用途是,如果您想读/写一组结构,这些结构不能被平台对齐均匀分割,因此已填充,但不能如此常见,从而保证设计中的这种选择。

    fread(3) :

    从流指向的流,将它们存储在给定的位置 通过ptr。

    函数fwrite()写入数据的nmemb元素,每个元素大小为个字节 long,指向流指向的流,从位置获取它们 由ptr提供。

    fread()和fwrite()返回成功读取或写入的项目数 (即,不是字符数)。如果发生错误,或 到达文件末尾时,返回值为短项计数(或零)。

    7 回复  |  直到 5 年前
        1
  •  77
  •   ghilesZ Peter Miehle    5 年前

    差异 fread(buf, 1000, 1, stream) fread(buf, 1, 1000, stream) 就是说,在第一种情况下,如果文件较小,则只能得到一个1000字节的块,或者什么都没有,而在第二种情况下,文件中的所有内容都小于或等于1000字节。

        2
  •  23
  •   Powerlord    17 年前

    这取决于你是怎么做的 fread 实现了。

    对fgetc()函数和 结果以读取顺序存储在 无符号字符的数组 覆盖对象。

    fgetc 也有以下说明:

    由于fgetc()对字节进行操作, 读一个由 字符“)可能需要多次调用 到fgetc()。

    SUS指出,这实际上取自ISO C文件。

        3
  •  15
  •   nos    15 年前

    许多文件系统都是基于记录的,因此,为了高效地满足这些文件系统的要求,您必须指定项的数量(“记录”),从而允许fwrite/fread在存储上作为记录而不仅仅是字节流进行操作。

        4
  •  9
  •   Tommy    8 年前

    size_t fread_buf( void* ptr, size_t size, FILE* stream)
    {
        return fread( ptr, 1, size, stream);
    }
    
    
    size_t fwrite_buf( void const* ptr, size_t size, FILE* stream)
    {
        return fwrite( ptr, 1, size, stream);
    }
    

    至于参数的基本原理 fread() / fwrite() ,我的K&R很久以前了,所以我只能猜测。我认为一个可能的答案是Kernighan和Ritchie可能只是认为在对象数组上执行二进制I/O是最自然的。此外,他们可能认为在某些体系结构上,块I/O实现起来更快/更容易,或者更容易。

    尽管C标准规定 fread() fgetc() fputc()

    fread()

    如果 size 函数是否也读取到 size - 1 超出其报告范围的其他字符。 fread(buf, 1, size * n, stream); 而不是 fread(buf, size, n, stream);

    基本上,他是这么说的 fread() 的接口已断开。对于 他指出,“书写错误通常很少,所以这不是一个主要缺点”——我不同意这种说法。

        5
  •  3
  •   dolch    17 年前

        6
  •  1
  •   supercat    8 年前

    对于可以避免读取任何部分记录的实现来说,使用单独的大小和计数参数可能是有利的。如果要从管道之类的对象中使用单字节读取,即使使用的是固定格式的数据,也必须考虑记录在两次读取中被分割的可能性。如果可以改为请求(例如,当有293个字节可用时,非阻塞读取最多40个记录,每个记录10个字节),并让系统返回290个字节(29个完整记录),同时保留3个字节以备下次读取,则会方便得多。

    我不知道fread的实现能在多大程度上处理这样的语义,但它们在承诺支持它们的实现上肯定很方便。

        7
  •  -2
  •   Vanuan tacaswell    14 年前

    我认为这是因为C缺少函数重载。如果有的话,那么尺寸将是多余的。但在C语言中,不能确定数组元素的大小,必须指定一个。

    考虑一下:

    int intArray[10];
    fwrite(intArray, sizeof(int), 10, fd);
    

    如果fwrite接受字节数,则可以写入以下内容:

    int intArray[10];
    fwrite(intArray, sizeof(int)*10, fd);
    

    但它只是效率低下。您将有sizeof(int)乘以更多的系统调用。

    在某些系统上(由于对齐),如果不创建副本并进行移位,则无法访问整数的一个字节。