[英]Reading and writing to the same file using the same fstream
我有一个已经包含一些数据(例如8 kB)的文件。 我想从文件的开头读取一些内容,然后从我完成读取的位置开始覆盖数据。 因此,我尝试使用以下代码:
std::fstream stream("filename", std::ios::in | std::ios::out | std::ios::binary);
char byte;
stream.read(&byte, 1);
// stream.seekp(1);
int bytesCount = 4096;
auto bytesVec = std::vector<char>(bytesCount, 'c');
char* bytes = bytesVec.data();
std::cout << stream.bad() << std::endl;
stream.write(bytes, bytesCount);
std::cout << stream.bad() << std::endl;
如果我执行这个代码,第一个bad()
返回false
,但第二个返回true
并没有什么实际被写入。
如果我将bytesCount
减小到小于4096(大概是某些内部缓冲区的大小)的任何内容,则第二个bad()
返回false
,但是仍然没有任何写入。
如果我取消对seekp()
行的注释,则写入将开始工作: bad()
返回false
并且实际写入了字节。
为什么在这里seekp()
必需的? 为什么没有它就不起作用? seekp()
是执行此操作的正确方法吗?
我在Windows 7上使用Visual Studio 2012。
您对在以MS的fstream
库从其C <stdio.h>
实现继承的更新模式下打开的文件进行的读和写操作的混合混杂方面受到限制。
C标准(我引用了C99,但在这一点上与C89并无区别)在7.19.5.3/6中指出:
当使用更新模式打开文件时(上面的模式参数值列表中的第二个或第三个字符“ +”),输入和输出都可以在关联的流上执行。 但是,在没有中间调用fflush函数或文件定位函数(fseek,fsetpos或rewind)的情况下, 输出之后不能直接输入,在没有中间调用文件位置的情况下 , 输入之后不能直接输出。 function ,除非输入操作遇到文件结尾。
(我的重点)。
因此,演变为C fseek
的stream.seekp(1)
解决方案是正确的。
GNU C库没有此标准限制,因此发布的代码在使用GCC构建时可以按预期工作。
MS <fstream>
库在继承此限制时符合C ++标准。 fstream
是使用basic_filebuf<charT,traits>
。 在(C ++ 11)Standard关于此模板的说明中,在§27.9.1.1/2中,它仅表示:
读取和写入由basic_filebuf类的对象控制的序列的限制与使用标准C库FILEs进行读取和写入的限制相同。
您可能需要研究捆绑流-http: //www.cplusplus.com/reference/ios/ios/tie/
这使得每次输入读取输出都会自动刷新,这是我认为您想要的行为,尽管它确实需要单独的输入和输出流
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.