简体   繁体   English

c中的fclose函数,如果调用fclose作为文件处理程序,为什么fread()有效但fwrite()不起作用

[英]fclose function in c, Why fread() works but not fwrite() if you call fclose for file handler

Why is it if we read a file with fread() and don't include fclose to close the same same file reference but still it works. 如果我们使用fread()读取文件并且不包含fclose来关闭相同的文件引用,但仍然可以运行,为什么会这样呢。

However if we forgot to include fclose after fwrite then it doesn't work.ie no writing on file reflects. 但是,如果我们忘记在fwrite之后再加上fclose,那么它就行不通了。

fread() , as the name implies, reads data from a file. 顾名思义, fread()从文件读取数据。 Logically, it can't return until it's either actually read the data (stored it in the buffer you provided) or reported an error. 从逻辑上讲,它只有在实际读取数据(将其存储在您提供的缓冲区中)或报告错误后才能返回。 As soon as fread() returns, you can use the data. fread()返回后,即可使用数据。

fwrite() , on the other hand, can go through multiple layers of buffering, in the C runtime library, in the OS, and elsewhere. 另一方面, fwrite()可以在C运行时库,OS和其他地方经历多层缓冲。 fwrite() returns when it's processed your data and written it ... somewhere . fwrite()在处理fwrite()数据并将其写到某处时返回 There's no guarantee that it's actually written to the physical file until you either flush it ( fflush(outfile); ) or close it ( fclose(outfile); ). 在您刷新它( fflush(outfile); )或关闭它( fclose(outfile); )之前,无法保证它实际上已写入物理文件。 As soon as fwrite() returns, you can do what you like with the data you passed to it (it's been copied), but that's all you can assume. 一旦fwrite()返回,您就可以对传递给它的数据(已被复制)进行所需的操作,但这只是您可以假设的。

If your program terminates normally, it will implicitly close (and therefore flush) all open output files. 如果您的程序正常终止,它将隐式关闭(并刷新)所有打开的输出文件。 If your program terminates abnormally, this may not happen. 如果您的程序异常终止,则可能不会发生。

(Actually, I think there are some cases where data may not physically arrive in the file even after fclose() or fflush() .) (实际上,我认为在某些情况下,即使在fclose()fflush()之后,数据也可能无法物理到达文件中。)

File access is buffered. 文件访问被缓冲。 When you execute an fread() , it can't return until the actual data has been read, but if you execute an fwrite() then it can return after placing the written data in the file buffer but before writing it to the underlying file. 当执行fread() ,它只有在读取实际数据后才能返回,但是如果执行fwrite()则可以在将已写入的数据放入文件缓冲区之后但在将其写入基础文件之前返回。

A side-effect of fclose() is flushing the file buffers - you could also use fflush() after fwrite() to achieve the same effect. fclose()的副作用是刷新文件缓冲区-您也可以在fwrite()之后使用fflush() fwrite()来达到相同的效果。

Because the read operation must obviously complete after the fread function returned - having actually read the data in your buffer is one of the postconditions of fread , otherwise you couldn't be sure that you can do anything useful with the data in the buffer after calling fread 1 . 因为读操作显然必须在返回fread函数之后完成-实际读取缓冲区中的数据是fread的后置条件之一,否则您无法确定可以在调用后对缓冲区中的数据做任何有用的事情fread 1

fwrite , instead, can (and will) do write buffering - it will accumulate data in its private buffer before passing it to the operating system to actually write it down in the file; fwrite可以(并且将)进行写缓冲-它会在将其数据传递给操作系统以将其实际记入文件之前在其专用缓冲区中累积数据; this is possible (and convenient) since, as far as your program is concerned, this thing is completely transparent: the data has already been stored in some other buffer, if you read back from the same stream you'll find your data there, and still you get the performance improvements from the caching. 这是可能的(并且很方便),因为就您的程序而言,这件事是完全透明的:数据已经存储在其他缓冲区中,如果您从同一流中回读,则可以在其中找到数据,仍然可以从缓存中获得性能改进。 Still, if you need your data to go immediately to the OS, you can use fflush . 但是,如果您需要数据立即进入操作系统,则可以使用fflush

Incidentally, even if you don't call fclose right away the standard guarantees that, in case of normal program termination, the streams are automatically closed, and thus their content is flushed. 顺便说一句,即使您没有立即调用fclose ,标准也保证在正常程序终止的情况下,流将自动关闭,因此将刷新其内容。


  1. By the way, there are instead scenarios where is useful to get data only if it's available or to start read operations and check later if the data have been actually read - and that's why operating systems provide nonblocking and asynchronous IO functions. 顺便说一下,在某些情况下,只有在可用时才可以获取数据,或者在以后开始读取操作并随后实际检查是否已读取数据时才有用-这就是操作系统提供非阻塞和异步IO功能的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM