fread / fwrite以尺寸和数量作为参数的基本原理是什么?

我们在这里讨论了为什么fread和fwrite为每个成员设置一个大小,并计算并返回读写成员的数量,而不是仅仅考虑缓冲区和大小。 我们可以想到的唯一用途是如果你想读/写一个不能被平台alignment平均整除的结构体数组,并且因此已经被填充,但是不能这样常见以至于不能保证这个select在devise中。

FREAD(3)

函数fread()从stream指向的stream中读取数据的nmemb个元素,每个size个字节长,将它们存储在ptr给定的位置。

函数fwrite()将数据的nmemb元素(每个字节长度)写入stream指向的stream,从ptr给出的位置获取它们。

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

这是基于如何实施fread 。

单一UNIX规范说

对于每个对象,应调用fgetc()函数进行大小调整,并按读取顺序将结果存储在一个无符号字符数组中,该数组正好覆盖该对象。

fgetc也有这样的说明:

由于fgetc()以字节为单位进行操作,读取由多个字节(或“多字节字符”)组成的字符可能需要多次调用fgetc()。

当然,这比UTF-8更像花式的可变字节字符编码。

SUS注意到这实际上取自ISO C文件。

fread(buf,1000,1,stream)和fread(buf,1,1000,stream)的区别在于,在第一种情况下,只有一个1000字节的块或nuthin块,如果文件较小,第二种情况是,文件中的所有内容less于1000字节。

这是纯粹的猜测,但是在当时(有些还在),很多文件系统并不是简单的硬盘驱动器上的字节stream。

许多文件系统是基于logging的,因此为了以一种有效的方式来满足这样的文件系统,必须指定项目的数量(“logging”),允许fwrite / fread在存储上作为logging操作,而不仅仅是字节stream。

在这里,让我解决这些function:

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在某些体系结构上执行起来会更快/更容易。

尽pipeC标准规定了用fgetc()fputc() fwrite()来实现fread()fwrite() ,但要记住,标准在C被K&R定义后很久才出现,标准中指定的东西可能不一直在原devise师的想法。 K&R的“The C Programming Language”中所说的内容甚至有可能与第一次devise语言的时候不一样。

最后,这是PJ Plauger在“标准C库”中对fread()

如果size (second)参数大于1,则无法确定函数是否也读取了size - 1超出了报告的额外字符数。 作为一个规则,你最好把函数调用为fread(buf, 1, size * n, stream); 而不是fread(buf, size, n, stream);

基本上,他是说fread()的界面已经坏了。 对于fwrite()他指出:“写错误通常是很less见的,所以这不是一个主要的缺点” – 我不同意的一个陈述。

有可能回到文件I / O实现的方式。 (当天回来)写入/读取块中的文件可能会更快,然后一次写入所有内容。

我认为这是因为C缺乏函数重载。 如果有一些,大小将是多余的。 但是在C中,你不能确定一个数组元素的大小,你必须指定一个。

考虑这个:

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

如果fwrite接受的字节数,你可以写下面的内容:

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

但是效率不高。 你会有sizeof(int)乘以更多的系统调用。

另一点应该考虑的是,你通常不希望将数组元素的一部分写入文件。 你想要的整数或没有。 fwrite返回成功写入的许多元素。 所以如果你发现一个元素只有2个低字节被写入,你会怎么做?

在一些系统上(由于alignment),你不能访问一个整数的一个字节,而不会创build一个拷贝和移位。