fread 和 fwrite 有没有失败?如何处理?

Posted

技术标签:

【中文标题】fread 和 fwrite 有没有失败?如何处理?【英文标题】:do fread and fwrite have failure? how to handle this? 【发布时间】:2012-03-12 11:28:40 【问题描述】:

当我使用 fread(C 语言)从文件中读取时,fread 的返回值有时会是 0。

按照手册的建议:

fread() 和 fwrite() 返回成功读取的项目数或 写的

我必须写这样的代码吗?

int bytes_read;
while((bytes_read = fread(buffer, sizeof(int), 1, fp)) == 0) 


我们是否总是需要检查 fread 或 fwrite 是否成功?

【问题讨论】:

【参考方案1】:

不,如果freadfwrite 返回的记录数少于预期的读取或写入记录数,则执行这样的重试循环是没有意义的。也就是说,stdio 不像低级的readwrite 操作会导致“短”读或写。

如果fread 返回的记录数少于请求的记录数,则说明您遇到了 EOF 或严重的读取错误。您可以通过检查feof()ferror() 来区分它们。

同样,如果fwrite 返回的记录数少于请求的记录数,您要么磁盘空间不足,要么遇到严重的写入错误。

无论如何,由于 stdio 的缓冲使得基本上无法知道成功写入了多少,所以如果遇到写入错误,通常需要考虑文件丢失并中止整个操作。

【讨论】:

【参考方案2】:

http://pubs.opengroup.org/onlinepubs/000095399/functions/fread.html

成功完成后,fread() 将返回成功读取的元素数,仅当遇到读取错误或文件结尾时,该数小于 nitems。如果 size 或 nitems 为 0,fread() 将返回 0,并且数组的内容和流的状态保持不变。否则,如果发生读错误,则应设置流的错误指示符,并设置errno来指示错误。

http://pubs.opengroup.org/onlinepubs/007904875/functions/fwrite.html

fwrite() 函数应返回成功写入的元素数,如果遇到写入错误,可能小于 nitems。如果 size 或 nitems 为 0,fwrite() 将返回 0 并且流的状态保持不变。否则,如果发生写入错误,则应设置流的错误指示符,并设置errno以指示错误

必须使用 ferror() 或 feof() 函数来区分错误条件和文件结束条件。

【讨论】:

【参考方案3】:

如果 fread 失败,它通常会继续失败。通常是因为它到达了文件的末尾,但也可能是其他原因。如果失败,您通常不会再试一次。

【讨论】:

【参考方案4】:

是的。

返回值应始终为 count

如果不是 - 您应该使用 ferror()feof() 来确定您是否已到达文件末尾和/或遇到错误。

忽略错误和/或意外情况会导致不可靠的软件对毫无戒心的用户造成影响。

http://www.cplusplus.com/reference/clibrary/cstdio/fread/

http://pubs.opengroup.org/onlinepubs/000095399/functions/fread.html

【讨论】:

不,整个操作成功时返回值是count,而不是size*count @R.. - 呃...我不认为这是正确的。你确定吗?您有不同意我发布的文档的文档吗? @R.. - 我很确定如果您请求“5”个大小为“10”的项目,那么响应应该是“50”而不是“5”。 R.是对的。 fread()fwrite() 返回成功读取或写入的项目数,而不是字节数。 如果 cplusplus.com 声称这是字节数,我不会感到惊讶......该网站充满了错误信息,永远不应被引用为权威。

以上是关于fread 和 fwrite 有没有失败?如何处理?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理失败的 DllImport?

C语言如何用fread()和fwrite()实现对文本文件的整行读写呢,文本文件中每一行的字符个数不一定相同

Meteor 如何处理依赖失败的乐观操作?

如何处理调用 sqlplus 的批处理文件中的错误,因为 sqlplus 没有在错误或失败时设置 ERRORLEVEL?

如何处理 WCF 的 MSMQ 绑定中的消息失败

消息中间件 MQ 如何处理消费失败的消息?