天天看点

关于文件流的操作

最近在学习socket编程,做了一个小项目,就是传输大文件,具体的内容就是使用epoll LT模式,客户端发送文件到服务端,服务端再把收到的内容完整的写入另一个文件中。

测试过程中不知道为什么传输完成之后服务端写入的新文件总是比客户端传来的文件内容少了几千个字节,也有对服务器程序进行验证,服务器确确实实有接收到这些文件内容(少了的那几千个字节),也有确实有通过ofstream输出文件流输出到指定的文件中。

一直很纳闷,找不到解决方案,后来找到了一篇博文说在操作文件流时,当不再使用该文件流的时候,一定要进行close操作,但是也没有说明为什么。然后我就着手去修改了一下程序,在客户端关闭了的时候对ofstream进行close操作,发现问题真的解决了!

然后就去了解了一下为什么需要这样做,找到了以下答案:

在《C++ Primer》第五版8.1.3中有这样一句话“每个输出流都管理一个缓冲区,用来保存程序读写的数据。例如,如果执行下面代码‘ os << “please enter a value”; ’ 文本串可能会立即打印出来,但也有可能被操作系统保存在缓冲区中,随后再打印。”

关于文件流的操作

通过这段话其实也就明白了为什么需要在操作文件流之后对文件流进行close操作了(但是其实也还得要理解一下刷新缓冲区的操作!),对文件流进行close会刷新缓冲区(应该不是每个io流进行close都会进行刷新缓冲区操作,因为没有测试过所以不敢下结论,但是对ofstream进行close是会的,因为我测试过),当你没有进行close操作的时候,此时缓冲区中还有一些数据未被输出,如果程序突然中断/异常退出,缓冲区中的数据没有得到处理,所以就造成了数据丢失的情况!

当然,也可以在每次输出操作之后手动刷新缓冲区,这样即使没有close也不会丢失数据,但是这种习惯不好,而且这种操作也丧失了缓冲区机制带来的好处之一(可以将程序的多个输出操作合并成一个单一的系统级写操作),所以还是要养成open与close成对出现的好习惯!