下面是两个将50,000,000字节写入文件的程序.
第一个用C语言编写的程序利用一个缓冲区,一旦填充到任意值,写入磁盘,然后重复该过程直到写入所有50,000,000个字节.我注意到,当我增加缓冲区的大小时,程序运行时间更短.例如,在BUFFER_SIZE = 1时,程序花了大约88.0463秒,而在BUFFER_SIZE = 1024时,程序只需要大约1.7773秒.我记录的最佳时间是BUFFER_SIZE = 131072.当BUFFER_SIZE增加高于此值时,我注意到它开始实际需要更长时间.
第二个用C++编写的程序利用ofstream一次写入一个字节.令我惊讶的是,该程序只用了1.87秒就可以运行了.我预计它需要一分钟左右,就像使用BUFFER_SIZE = 1的C程序一样.显然,C++ ofstream处理文件写入的方式与我想象的不同.根据我的数据,它的表现与BUFFER_SIZE = 512的C文件非常相似.它是否使用某种幕后缓冲区?
这是C程序:
const int NVALUES = 50000000; //#values written to the file
const char FILENAME[] = "/tmp/myfile";
const int BUFFER_SIZE = 8192; //# bytes to fill in buffer before writing
main()
{
int fd; //File descriptor associated with output file
int i;
char writeval = '\0';
char buffer[BUFFER_SIZE];
//Open file for writing and associate it with the file descriptor
//Create file if it does not exist; if it does exist truncate its size to 0
fd = open(FILENAME, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
for(i=0;i<NVALUES;i++)
{
//Package bytes into BUFFER_SIZE chunks
//and write a chunk once it is filled
buffer[i%BUFFER_SIZE] = writeval;
if((i%BUFFER_SIZE == BUFFER_SIZE-1 || i == NVALUES-1))
write(fd, buffer, i%BUFFER_SIZE+1);
}
fsync(fd);
close(fd);
}
Run Code Online (Sandbox Code Playgroud)
这是C++程序:
int main()
{
ofstream ofs("/tmp/iofile2");
int i;
for(i=0; i<50000000; i++)
ofs << '\0';
ofs.flush();
ofs.close();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
感谢您的时间.
Mat*_* M. 12
是的,所有流操作都是缓冲的,但默认情况下,标准输入,输出和错误输出不是这样,与C IO的交互就不那么令人惊讶了.
如前所述,有一个streambuf在幕后使用的基类.它提供了自己的缓冲区,其大小是一个实现细节.
您可以(通过实验)检查此缓冲区的使用量streambuf::in_avail,假设输入文件流和输出文件流设置为具有相同的缓冲区大小...
您可以在此处执行另外两项可能感兴趣的操作:
streambuf流使用的对象,以切换到自定义版本streambuf对象使用的缓冲区两者都应该在创建流之后或之后完成flush,以免某些数据丢失...
要说明缓冲区更改,请查看streambuf::putsetbuf:
#include <fstream>
#include <vector>
int main () {
std::vector<char> vec(512);
std::fstream fs;
fs.rdbuf()->pubsetbuf(&vec.front(), vec.size());
// operations with file stream here.
fs << "Hello, World!\n";
// the stream is automatically closed when the scope ends, so fs.close() is optional
// the stream is automatically flushed when it is closed, so fs.flush() is optional
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在你可以重复你在C中做的实验来找到最佳位置:)