C++ fstream seekg()、seekp() 和 write()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15670359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
fstream seekg(), seekp(), and write()
提问by raphnguyen
I'm looking for some clarification on how seekg()
and seekp()
works with respect to when you are writing to a file. Say for instance I had a file like so:
我正在寻找有关写入文件时如何seekg()
以及如何seekp()
工作的一些说明。比如说我有一个这样的文件:
offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
Now I want to open the file and do some seeks to read and write values.
现在我想打开文件并尝试读取和写入值。
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
Now I want to write to the end of the file. Since the seekg()
function only moves the seek cursor, my seekp()
cursor should still be at the end of the file right? So:
现在我想写到文件的末尾。由于该seekg()
函数只移动搜索光标,我的seekp()
光标应该仍然在文件的末尾,对吗?所以:
int newKey = 12;
file.write((char *) &newKey, sizeof(int));
should make my file now look like:
应该让我的文件现在看起来像:
offset 0: 2
offset 4: 4
offset 8: 6
offset 12: 8
offset 16: 10
offset 20: 12
Now what happens to my file if I choose to seek to an offset and write its value as the offset to the value that was just inserted. For example, I want offset 8
to hold eofOffset = 20
since we just inserted 12 at that offset.
现在,如果我选择寻找偏移量并将其值作为偏移量写入刚刚插入的值,我的文件会发生什么情况。例如,我想offset 8
保持,eofOffset = 20
因为我们刚刚在该偏移量处插入了 12。
If I do:
如果我做:
file.seekp(8, ios::beg);
file.write((char *) &eofOffset, sizeof(int));
does it correctly rewrite my file to look like this:
它是否正确地将我的文件重写为如下所示:
offset 0: 2
offset 4: 4
offset 8: 20
offset 12: 8
offset 16: 10
offset 20: 12
Please let me know if I am making any errors using the seekg()
and seekp()
functions.
如果我在使用seekg()
和seekp()
函数时犯了任何错误,请告诉我。
回答by user657267
The class template std::basic_filebuf
holds a single file position
类模板std::basic_filebuf
保存单个文件位置
§ 27.9.1.1
- The class basic_filebuf associates both the input sequence and the output sequence with a file.
- The restrictions on reading and writing a sequence controlled by an object of class basic_filebuf are the same as for reading and writing with the Standard C library FILEs.
- In particular:
- If the file is not open for reading the input sequence cannot be read.
- If the file is not open for writing the output sequence cannot be written.
- A joint file position is maintained for both the input sequence and the output sequence.
第 27.9.1.1 节
- 类 basic_filebuf 将输入序列和输出序列与文件相关联。
- 读取和写入由类 basic_filebuf 的对象控制的序列的限制与使用标准 C 库文件读取和写入的限制相同。
- 特别是:
- 如果未打开文件进行读取,则无法读取输入序列。
- 如果文件未打开用于写入,则无法写入输出序列。
- 为输入序列和输出序列维护一个联合文件位置。
What this means is that when you use a std::basic_fstream
, which by default uses a std::basic_filebuf
, the single file position is moved by both seekp()
and seekg()
; unless you use a separate variable to store one of the positions so you can then seek back to it, you cannot keep track of put and get positions independently.
这意味着当您使用 a 时std::basic_fstream
,默认情况下使用 a std::basic_filebuf
,单个文件位置由seekp()
和移动seekg()
;除非您使用单独的变量来存储其中一个头寸,以便您可以返回到它,否则您无法独立跟踪看跌期权和获得头寸。
The implications of point 2 are that between reads and writes on an fstream
you must either flush the buffer or seek the file position when changing from output to input, and you must either be at the end of the file or seek the file position when changing from input to output.
第 2 点的含义是,在读取和写入之间,fstream
您必须在从输出更改为输入时刷新缓冲区或查找文件位置,并且您必须位于文件末尾或在更改时查找文件位置输入到输出。
For detail on these restrictions, see section 7.19.5.3/7 of the C99 standard ("The fopen
function"), or 7.21.5.3/7 of C11.
有关这些限制的详细信息,请参阅 C99 标准的第 7.19.5.3/7 节(“fopen
函数”)或 C11 的 7.21.5.3/7。