C++ 如何在io.h中定义的写操作中添加写缓冲区
我在io.h中使用write(fd、buffer、count)将缓冲区写入文件描述符 现在我发现了巨大的性能问题,因为每次我调用“write”时,它都会执行IO操作 我想在将内容写入文件之前添加一个缓冲区 最好的方法是什么 我搜索并找到了这个: http://www.java2s.com/Tutorial/Cpp/0240__File-Stream/filedescriptoroutbuffer.htm 我应该使用这种方法并集成到代码中吗?这是我应该采取的好方法吗 但在它里面,我看不到如何定义缓冲区大小 以下是最终代码:C++ 如何在io.h中定义的写操作中添加写缓冲区,c++,buffer,C++,Buffer,我在io.h中使用write(fd、buffer、count)将缓冲区写入文件描述符 现在我发现了巨大的性能问题,因为每次我调用“write”时,它都会执行IO操作 我想在将内容写入文件之前添加一个缓冲区 最好的方法是什么 我搜索并找到了这个: http://www.java2s.com/Tutorial/Cpp/0240__File-Stream/filedescriptoroutbuffer.htm 我应该使用这种方法并集成到代码中吗?这是我应该采取的好方法吗 但在它里面,我看不到如何定义缓
class fdoutbuf : public std::streambuf {
protected:
enum { size = 4096 };
int fd; // file descriptor
char buf_[size];
public:
// constructor
fdoutbuf (int _fd) : fd(_fd) {
setp(this->buf_, this->buf_ + size - 1);
}
protected:
// write one character
virtual int overflow (int c){
if (c != EOF) {
char z = c;
*this->pptr() = z;
this->pbump(1);
}
return this->sync() == -1? EOF: c;
}
virtual int sync(){
if (this->pbase() == this->pptr()) {
return 0;
}
int count(this->pptr() - this->pbase());
int rc = write(fd, this->buf_, count);
this->setp(this->buf_, this->buf_ + size - 1);
return count == rc? 0: -1;
}
};
class fdostream : public std::ostream {
protected:
fdoutbuf buf;
public:
fdostream (int fd) : std::ostream(0), buf(fd) {
rdbuf(&buf);
}
};
如果你用C++编写,你可以尝试使用<代码> STL< /COD>和<代码> /COD>输出到文件中。它已内置缓冲区,不存在速度问题。
< P>如果你用C++编写,你可以尝试使用<代码> STL< /COD>和<代码> /COD>输出到文件中。它已经内置了缓冲区,并且在速度上没有这样的问题。创建缓冲基础设施不是真正的火箭科学,但也不是完全微不足道的。就我个人而言,我只需要创建一个派生自std::streambuf
的类,或者使用流缓冲区抽象,或者使用流(可能我会使用后者,并接受大多数实现带来的较小性能影响)。这样做的工作相当简单(仅用于写作):
似乎有必要解释一下上面的流缓冲区实际上做了什么(考虑到下面冗长的讨论)。因此,这里有一个细分:
- 代码使用固定大小的缓冲区。这只是为了减少示例的大小:可以轻松扩展为使用分配的可变大小缓冲区,例如使用
:大小将成为默认参数std::vector
- 函数
设置流缓冲区使用的缓冲区,由三个指针组成:setp()
是缓冲区的开始,即pbase()
setp()的第一个参数
是缓冲区的结尾,即epptr()
setp()的第二个参数
设置为与pptr()
相同的值,但它是实际移动以指示下一个字符位置的指针。如果写入字符时这是pbase()
,则调用epptr()
overflow()
- 虚拟函数
可能具有导致缓冲区溢出的字符。除非用户代码使用参数overflow()
调用该函数,否则标准库调用该函数时就是这种情况。为了处理这个额外的字符,在可用空间不足的情况下,给缓冲区一个元素:可以在实际写入缓冲区之前将字符追加到缓冲区eof()
- 继承自
的std::streambuf
定义了许多函数来确定字符的属性。检查传递给traits_type
的参数时,将使用函数overflow()
,该函数将与流的整数类型的对象进行相等性比较。它将eq\u int\u type()
的参数与指示使用overflow()
获得的无效字符的值进行比较。traits类型的所有成员都是eof()
或static
s,即不需要使用此类型的对象。当使用typedef
的不同模板实例化时,使用std::basic\u streambuf
非常重要traits\u type
- 虽然缓冲区通常是
到pbase()
的,在这两个端点之间有epptr()
,但是pptr()
可以使用pptr()
移动到pbump(n)
之外:此函数只是将epptr()
添加到n
。这用于在调用pptr()
之前将currencnt字符放入缓冲区,后者只写入缓冲区的内容并重置它sync()
- 如果函数失败,
的返回为overflow()
。成功执行时,函数返回与eof()
不同的内容,通常使用作为参数传递的字符。由于参数可能是eof()
,仅返回参数是不够的,但是:如果它是eof()
,则需要将此值转换为其他有用的值,而这正是eof()
所做的:除非参数是not_eof()
在这种情况下,它会返回一些合适的其他值eof(),否则它将返回参数
- 虚拟函数
负责刷新缓冲区。在这种情况下,首先检查是否有需要执行的操作,如果有,则写入缓冲区的内容。这个函数实际上没有任何技巧,尽管我想如果sync()
失败,即返回的字符数少于缓冲区中的字符数,那么正确的技巧会更加小心。这个版本只是假装可以释放无法写入的字符,尽管它会指示错误write()
- 该函数仍然使用在缓冲区末尾保留一个字符空间的相同方法重置缓冲区
- 失败时,函数返回
,成功时返回-1
。别耍花招0
std::streambuf
的类,或者使用流缓冲区抽象,或者使用流(可能我会使用后者,并接受大多数实现带来的较小性能影响)。这样做的工作相当简单(仅用于写作):
似乎有必要解释一下上面的流缓冲区实际上做了什么(考虑到下面冗长的讨论)
struct fdbuf: std::streambuf {
enum { size = 4096 };
fdbuf(int fd): fd_(fd) { this->setp(this->buf_, this->buf_ + size - 1); }
int overflow(int c) {
if (!traits_type::eq_int_type(c, traits_type::eof())) {
*this->pptr() = traits_type::to_char_type(c);
this->pbump(1);
}
return this->sync() == -1? traits_type::eof(): traits_type::not_eof(c);
}
int sync() {
if (this->pbase() == this->pptr()) {
return 0;
}
int count(this->pptr() - this->pbase());
int rc = write(this->fd_, this->buf_, count);
this->setp(this->buf_, this->buf_ + size - 1);
return count == rc? 0: -1;
}
int fd_;
char buf_[size];
};