很久之前,我和Swalky在写Huffman
Tree压缩的时候,遇到了一个问题:我们想在一个已经写入了一些内容的文件中部(或头部)写一些内容(用于修改文件的一些meta信息),结果发现总是
不行。如果用ofstream的默认构造函数,文件原有内容就不会保留下来,如果用了ios::app,无论怎么用seekp来定位,所写的内容都会跟在
文件原有内容的最后面。怎么办呢?
本着RTFM的心态,他去看C++ Primer,我则去看TCPL,以及网上的C++ Reference( http://www.cplusplus.com/reference/ ):
mode
Flags describing the requested i/o mode for the
file. This is an object of type ios_base::openmode, which consists on a
combination of one or more of the following flags defined as member
constants:
flag value
opening mode
app
|
(app
end) Set the stream's position indicator to the end of the stream before each output operation. |
ate
|
(at e
nd) Set the stream's position indicator to the end of the stream on opening. |
binary
|
(binary
) Consider stream as binary rather than text. |
in
|
(in
put) Allow input operations on the stream. |
out
|
(out
put) Allow output operations on the stream. |
trunc
|
(trunc
ate) Any current content is discarded, assuming a length of zero on opening. |
我们注意到一个重要的区别:app会在每次写操作之前都把写指针置于文件末尾,而ate模式则只在打开时才将写指针置于文件末尾。于是我们非常兴奋地将ofstream置于ios::ate,结果发现seekp仍然不能正常工作。
于是我把TCPL的《流》一章反复读了几遍,尤其很认真地看了流的缓冲区streambuf的实现,我突然意识到,如果不赋予流读文件的能力,没有读的缓冲区,流就无法seekp到文件的中部。
我试着改用这段代码来构造流:
fstream(filename, ios::in|ios::out|ios::ate)
程序的运行成功了!我很兴奋,因为当时是通过对流的实现的分析推断出这个结论的。
后来有一次有人在群上问C中如何这么做,我经过一番实验,发现只有以r+模式打开文件,fseek才起作用。这其实仍是基于同样的原理。这里把C的fopen文档贴出来:
mode
C string containing a file access modes. It can be:
"r" |
Open a file for reading. The file must exist. |
"w" |
Create an empty file for writing. If a file with
the same name already exists its content is erased and the file is
treated as a new empty file. |
"a" |
Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist. |
"r+" |
Open a file for update both reading and writing. The file must exist. |
"w+" |
Create an empty file for both reading and writing.
If a file with the same name already exists its content is erased and
the file is treated as a new empty file. |
"a+" |
Open a file for reading and appending. All writing
operations are performed at the end of the file, protecting the
previous content to be overwritten. You can reposition (fseek
, rewind
)
the internal pointer to anywhere in the file for reading, but writing
operations will move it back to the end of file. The file is created if
it does not exist |
r+的意思是同时读写,而且该文件必须已经存在。用w+是错误的,因为它会把现存文件的所有内容清空。
最后附上当时的测试代码(用一个宏开关来分别测试C和C++):
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
using namespace std;
int main()
{
const char * original = "012345678901234567890123456789"; //30 chars
const char * overwrite = "abcdeabcde";
const char * filename = "test.txt";
fstream fout;
fout.open(filename, ios::out|ios::trunc); //destroy any current content
fout << original;
fout.close();
#define TESTING_CPP 1
#if TESTING_CPP
fout.open(filename, ios::in|ios::out|ios::ate);
fout.seekp(7);
fout << overwrite;
fout.close();
#else
FILE * fout_c;
if(fout_c = fopen(filename, "r+"))
{
fseek(fout_c, 7, SEEK_SET);
fprintf(fout_c, overwrite);
fclose(fout_c);
}
#endif //TESTING_CPP
fout.open(filename, ios::in);
while(!fout.eof())
{
cout << static_cast<char>(fout.get());
}
return 0;
}
分享到:
相关推荐
ofstream ofstream ofstream ofstream
ofstream ifstream 文件操作 是VC中的文件读入读出的基本操作!
ofstream和ifstream详细用法总结
c++使用流的方式写和读取磁盘上的文件,与c中fopen、fget、fput等函数的功能类似。
ofstream的使用方法--超级精细。C++文件写入、读出函数。
利用ifstream和ofstream写的文件分割和合并 用c++中的纯fstream写的文件分割和合并程序, 大家可以看看,加强一下c++中的文件操作
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间
(1) 使用ofstream 向一个文本文件中输出各种类型的数据,并打开文件观察结果: 整数、无符号整型、长整型、浮点型、字符串、…… (2) 用十进制、八进制、十六进制方式向文本文件中输出整数; (3) 使用控制...
ofstream的使用方法,包括打开文件,读写文件等一些操作
在编程总经常会用到读写文件,基本都是使用ofstream,ifstream,fstream
三个重要的输出流: – ostream – ofstream – ostringstream
本文介绍了对文本文件、二进制文件的读写打开关闭等操作,以及fstream、 ifstream、ofstream的使用及方法。
ofstream是从内存到硬盘,ifstream是从硬盘到内存,其实所谓的流缓冲就是内存空间; 在C++中,有一个stream这个类,所有的I/O都以这个“流”类为基础的,包括我们要认识的文件I/O,stream这个类有两个重要的运算符:
《文件IO操作开发笔记(二):使用Cpp的ofstream对磁盘文件存储进行性能测试以及测试工具》 https://hpzwl.blog.csdn.net/article/details/128626548
在C++中将数据输出到文件需要用到文件流,将数据输出到文件(即下图中的写文件)时会用到ofstream 类.下面就具体介绍如何将一段字符或数据输出到文件中并保存
1. Re:基2时域抽 3. 带通滤波 matl 5. C++ ofstrea 1. 基2时域抽取FF
ofstream 类支持磁盘文件输出 如果在构造函数中指定一个文件名,当构造这个文件时该文件是自动打开的 ofstream myFile("filename",iosmode); iosmode 可以在调用默认构造函数之后使用 open 成员函数打开文件 ...
主要介绍了C++中fstream,ifstream及ofstream用法,适合C++初学者学习文件流的操作,需要的朋友可以参考下
(1) 使用ofstream 向一个文本文件中输出各种类型的数据,并打开文件观察结果: 整数、无符号整型、长整型、浮点型、字符串、…… (2) 用十进制、八进制、十六进制方式向文本文件中输出整数; (3) 使用控制符...