我有一个已包含一些数据的文件(例如,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 .
2 回答
您可能想要查看绑定的流 - http://www.cplusplus.com/reference/ios/ios/tie/
这使得每次输入读取输出都会自动刷新,这是我认为你想要的行为,虽然它确实需要一个单独的输入和输出流
对于在更新模式下打开的文件(对MS的
fstream
库继承自其C<stdio.h>
实现)的读写操作的混合,您正在违反限制 .在7.19.5.3/6状态下,C标准(我引用C99,但这与C89没有区别):
(我的重点) .
所以你的
stream.seekp(1)
解决方案,它转换为Cfseek
,是正确的 .GNU C库没有此标准限制,因此当使用GCC构建时,您发布的代码按预期工作 .
MS
<fstream>
库在继承此限制时符合C标准 .fstream
是使用basic_filebuf<charT,traits>
实现的 . 在(C 11)标准对该模板的描述中,在第27.9.1.1/2节中,它只是说: