fstream seekg(),seekp()和write()

rap*_*yen 21 c++ file-io fstream seekg

我正在寻找关于你何时写文件的方式seekg()seekp()工作的一些说明.比方说我有一个像这样的文件:

offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
Run Code Online (Sandbox Code Playgroud)

现在我想打开文件并尝试读取和写入值.

fstream file;
file.open("file.txt", fstream::in |fstream::out | fstream::binary);
file.seekp(0, ios::end) // seek to the end of the file
int eofOffset = file.tellp(); // store the offset of the end-of-file, in this case 20

int key = 0;

file.seekg(12, ios::beg); // set the seek cursor to offset 12 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 8
file.seekg(8, ios::beg); // set the seek cursor to offset 8 from the beginning of the file
file.read((char *) &key, (int)sizeof(int)); // read in the next 4 bytes and assign it to key, in this case 6
Run Code Online (Sandbox Code Playgroud)

现在我想写到文件的末尾.由于该seekg()函数只移动搜索光标,我的seekp()光标应该仍然在文件的末尾吗?所以:

int newKey = 12;
file.write((char *) &newKey, sizeof(int));
Run Code Online (Sandbox Code Playgroud)

应该让我的文件现在看起来像:

offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
offset 20: 12
Run Code Online (Sandbox Code Playgroud)

现在,如果我选择寻找偏移并将其值作为刚刚插入的值的偏移量写入,我的文件会发生什么.例如,我想offset 8保持,eofOffset = 20因为我们刚刚在该偏移处插入了12.

如果我做:

file.seekp(8, ios::beg);
file.write((char *) &eofOffset, sizeof(int));
Run Code Online (Sandbox Code Playgroud)

它是否正确地重写我的文件看起来像这样:

offset 0: 2
offset 4: 4
offset 8: 20
offset 12: 8
offset 16: 10
offset 20: 12
Run Code Online (Sandbox Code Playgroud)

如果我使用seekg()seekp()函数出错,请告诉我.

use*_*267 22

类模板std::basic_filebuf包含单个文件位置

§27.9.1.1

  1. basic_filebuf类将输入序列和输出序列与文件相关联.
  2. 读取和编写由basic_filebuf类对象控制的序列的限制与使用Standard C库FILE读取和写入的限制相同.
  3. 特别是:
    • 如果文件未打开,则无法读取输入序列.
    • 如果文件未打开以进行写入,则无法写入输出序列.
    • 为输入序列和输出序列保持联合文件位置.

这意味着,当你使用std::basic_fstream,默认情况下使用std::basic_filebuf,单个文件的位置由两个移动seekp()seekg(); 除非你使用一个单独的变量来存储其中一个位置,然后你可以寻找它,你就无法独立跟踪看跌和获取头寸.

第2点的含义是,在读取和写入之间,fstream您必须刷新缓冲区或在从输出更改为输入时搜索文件位置,并且您必须位于文件的末尾或在更改时查找文件位置输入到输出.

有关这些限制的详细信息,请参阅C99标准的第7.19.5.3/7节(" fopen功能")或C11的7.21.5.3/7.