c++ - C++ ofstream文件写入是否使用缓冲区?

  显示原文与译文双语对照的内容
0 0

以下是两个写的程序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秒运行。 我预期要花一分钟左右,比如C 程序与BUFFER_SIZE = 1 。 显然,C++ ofstream处理文件写入不同于我以为。 根据我的数据,这正在执行非常类似C 文件使用BUFFER_SIZE = 512 。 它是否使用某种后台缓冲区?

这是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 = '';
    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);
}

这是C++程序:

int main()
{
    ofstream ofs("/tmp/iofile2");
    int i;
    for(i=0; i<50000000; i++)
        ofs << '';
    ofs.flush();
    ofs.close();
    return 0;
}

多谢你的宝贵时间

时间:原作者:6个回答

0 0

是的,ostream使用流缓冲区,部分的子类实例化类模板basic_streambuf 。 界面basic_streambuf旨在让实现者可以进行输出缓存是否存在带来的优势。

但是这个是高品质的实现问题。 实现无需这样做但任何称职实现将。

你可以阅读相关图书的第27 ISO标准,虽然也许可读性更强的源是C++标准库: 教程和Reference ( google搜索 ) 。?

原作者:
0 0

是的,所有的流操作进行缓冲处理,但默认情况下标准输入,输出和错误输出不这样和C 的交互IO也就少了。

正如前面提及,有一个基类streambuf使用的在幕后完成。 它提供有自己的缓冲区,其大小是一个实现细节。

你可以检查此缓冲区( 试验性地) 有多少是使用streambuf::in_avail,假设输入filestream和输出filestream,连着同一个缓冲区大小。。。

有两种其他操作可以在这里做,可能会有兴趣:

  • 你可以更改 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;
}

现在,你可以重复这个实验你刚才在C 查找最佳热点:)

原作者:
0 0

每个ofstream有一个。 filebuf可以读取指针,通过 rdbuf函数,它指向 streambuf对象,它就是:

streambuf对象通常关联有一个特定的字符序列,从中他们通过内部内存缓冲区读写数据。 缓冲区数组在内存中预计增幅在需要时同步使用的物理内容关联的字符序列。

我在公司内部的重要位,看来它并利用缓冲区,但我不知道或者没有发现哪种类型的缓冲区是。

原作者:
...