标准输入流使用的内部缓冲区 (pubsetbuf)
Internal buffer used by standard input stream (pubsetbuf)
我正在尝试设置输入流的内部缓冲区,但我在 C++17 中的实现没有为 istringstream 实现 pubsetbuf()。
我尝试了一些其他技术,但它们很慢或复制原始缓冲区。我正在寻找一种不进行任何复制的快速方法。
这与关于输出流的这个问题密切相关:
Setting the internal buffer used by a standard stream (pubsetbuf)
我已经密切关注了它,但是输入流的缓冲区仍然是 uninitialised/empty。
// Modified template from the other question about an output stream.
// This is for an input stream, but I can't get it to work.
template <typename char_type>
struct istreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> >
{
istreambuf(char_type* buffer, std::streamsize buffer_length)
{
// Set the "put" pointer to the start of the buffer and record its length.
this->setp(buffer, buffer + buffer_length);
}
};
int main()
{
ifstream infile(FILENAME, std::ifstream::binary);
if (!infile.is_open())
{
cerr << endl << "Failed to open file " << FILENAME << endl;
return 0;
}
// Works, but slow.
//istringstream local_stream;
//local_stream << infile.rdbuf();
// Works, but creates a copy.
//istringstream local_stream(&buffer[0]);
// Works, but creates a copy.
//local_stream.str(&buffer[0]);
// Read entire file into buffer.
infile.seekg(0, std::ios::end);
streampos length = infile.tellg();
infile.seekg(0, std::ios::beg);
vector<char> buffer(length);
//char* buffer = new char[length];
infile.read(&buffer[0], length);
// Doesn't work, but should point to original.
// It returns "this" (does nothing).
//local_stream.rdbuf()->pubsetbuf(&buffer[0], length);
// Works, but deprecated in C++98.
//std::istrstream local_stream(&buffer[0]);
//local_stream.rdbuf()->pubsetbuf(&buffer[0], length);
// I followed the example in the other question about an output stream,
// but I modified for an input stream. I can't get it to work. Any ideas?
istreambuf<char> istream_buffer(&buffer[0], length);
istream local_stream(&istream_buffer);
string str1, str2;
while (local_stream >> str1 && local_stream >> str2)
{
. . .
}
}
我解决了!找出不同。
template <typename char_type>
struct istreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> >
{
istreambuf(char_type* buffer, std::streamsize buffer_length)
{
// Set the "put" pointer to the start of the buffer and record its length.
//this->setp(buffer, buffer + buffer_length);
// Set the "get" pointer to the start of the buffer, the next item, and record its length.
this->setg(buffer, buffer, buffer + buffer_length);
}
};
我需要设置 "get" 指针,而不是 "put" 指针。现在效果很好。
我正在尝试设置输入流的内部缓冲区,但我在 C++17 中的实现没有为 istringstream 实现 pubsetbuf()。
我尝试了一些其他技术,但它们很慢或复制原始缓冲区。我正在寻找一种不进行任何复制的快速方法。
这与关于输出流的这个问题密切相关: Setting the internal buffer used by a standard stream (pubsetbuf)
我已经密切关注了它,但是输入流的缓冲区仍然是 uninitialised/empty。
// Modified template from the other question about an output stream.
// This is for an input stream, but I can't get it to work.
template <typename char_type>
struct istreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> >
{
istreambuf(char_type* buffer, std::streamsize buffer_length)
{
// Set the "put" pointer to the start of the buffer and record its length.
this->setp(buffer, buffer + buffer_length);
}
};
int main()
{
ifstream infile(FILENAME, std::ifstream::binary);
if (!infile.is_open())
{
cerr << endl << "Failed to open file " << FILENAME << endl;
return 0;
}
// Works, but slow.
//istringstream local_stream;
//local_stream << infile.rdbuf();
// Works, but creates a copy.
//istringstream local_stream(&buffer[0]);
// Works, but creates a copy.
//local_stream.str(&buffer[0]);
// Read entire file into buffer.
infile.seekg(0, std::ios::end);
streampos length = infile.tellg();
infile.seekg(0, std::ios::beg);
vector<char> buffer(length);
//char* buffer = new char[length];
infile.read(&buffer[0], length);
// Doesn't work, but should point to original.
// It returns "this" (does nothing).
//local_stream.rdbuf()->pubsetbuf(&buffer[0], length);
// Works, but deprecated in C++98.
//std::istrstream local_stream(&buffer[0]);
//local_stream.rdbuf()->pubsetbuf(&buffer[0], length);
// I followed the example in the other question about an output stream,
// but I modified for an input stream. I can't get it to work. Any ideas?
istreambuf<char> istream_buffer(&buffer[0], length);
istream local_stream(&istream_buffer);
string str1, str2;
while (local_stream >> str1 && local_stream >> str2)
{
. . .
}
}
我解决了!找出不同。
template <typename char_type> struct istreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> > { istreambuf(char_type* buffer, std::streamsize buffer_length) { // Set the "put" pointer to the start of the buffer and record its length. //this->setp(buffer, buffer + buffer_length); // Set the "get" pointer to the start of the buffer, the next item, and record its length. this->setg(buffer, buffer, buffer + buffer_length); } };
我需要设置 "get" 指针,而不是 "put" 指针。现在效果很好。