2

我想知道是否可以使用“fstream”从二进制文件中读取一个字节,然后更改该字节并将其写回。我尝试了这段代码,但它没有用,也没有任何反应,但我确信它读取正确。

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
file.seekg(0, ios::end);
int size=file.tellg();
file.seekg(0,ios::beg);
char buffer;    
for(int i=0;i<size;i++)
{
    file.read((char*)&buffer,sizeof(char));
    buffer=(buffer+7)%256;
    file.write((char*)&buffer, sizeof(char));
}

像这样阅读后,我是否应该将文件指针取回一个字节:

file.seekg(-1, ios::cur);

提前致谢。

4

4 回答 4

6

是的。正如您在问题中建议的那样,如果要覆盖先前读取的字节,则需要使用 seekg 调整文件指针的位置。每次读取后,文件指针将位于读取字节之后。

于 2010-02-23T09:42:31.347 回答
2

您应该将指针移回先前读取的字节数;所以用char -1。

file.seekg(-1, std::ios::cur);

请考虑在修改数据时它必须具有相同的字节大小,否则您将覆盖文件中的其他数据。

于 2010-02-23T09:45:05.087 回答
1

读写使用相同的位置指针。因此,如果您希望能够读取连续的值,要重写一个值,您应该将指针倒回到读取的位置,对吧?

也就是说,在您的情况下,读取数据块,然后在内存中转换它们,然后将它们写回可能会更有效。

于 2010-02-23T09:44:21.773 回答
0

首先,您必须始终检查实际打开的文件:

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
if ( ! file.is_open() ) {
    throw "open failed";
}

然后,您必须始终检查您期望工作的读取和写入是否有效:

if ( ! file.read((char*)&buffer,sizeof(char)) ) {
   throw "read failed";
}

最后,您应该检查您使用的打开标志的组合在您的特定平台上是否有效 - 请参阅为什么我不能在 Mac OS X 上读取和附加 std::fstream?对此进行一些讨论 - 我建议删除代码中的 ios::ate 标志。

于 2010-02-23T10:16:41.440 回答