Mar*_*nto 37 c++ memory optimization stream stringstream
为了提高从文件读取的性能,我试图将大(几MB)文件的整个内容读入内存,然后使用istringstream来访问信息.
我的问题是,哪个是读取此信息并将其"导入"到字符串流中的最佳方法?这种方法的一个问题(参见下文)是在创建字符串流时,缓冲区被复制,内存使用量增加一倍.
#include <fstream>
#include <sstream>
using namespace std;
int main() {
ifstream is;
is.open (sFilename.c_str(), ios::binary );
// get length of file:
is.seekg (0, std::ios::end);
long length = is.tellg();
is.seekg (0, std::ios::beg);
// allocate memory:
char *buffer = new char [length];
// read data as a block:
is.read (buffer,length);
// create string stream of memory contents
// NOTE: this ends up copying the buffer!!!
istringstream iss( string( buffer ) );
// delete temporary buffer
delete [] buffer;
// close filestream
is.close();
/* ==================================
* Use iss to access data
*/
}
Run Code Online (Sandbox Code Playgroud)
Luc*_*lle 42
std::ifstream有一个方法rdbuf(),返回一个指针filebuf.然后你可以"推" filebuf到你的stringstream:
#include <fstream>
#include <sstream>
int main()
{
std::ifstream file( "myFile" );
if ( file )
{
std::stringstream buffer;
buffer << file.rdbuf();
file.close();
// operations on the buffer...
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:由于马丁在纽约的言论答记者问,这可能不是最快的解决方案,因为stringstream的operator<<将字符读filebuf字符.你可能想检查他的答案,他在那里使用你以前ifstream的read方法,然后将stringstream缓冲区设置为指向先前分配的内存.
Mar*_*ork 41
好.我并不是说这比阅读文件更快
但是这是一种创建缓冲区的方法,在将数据读入缓冲区之后,将其直接用作stringstream的源.
NB值得一提的是std :: ifstream是缓冲的.它以(相对较大的)块的形式从文件中读取数据.对缓冲区执行流操作,仅在需要更多数据时返回到文件以进行另一次读取.因此,在将所有数据吸入内存之前,请确认这是瓶颈.
#include <fstream>
#include <sstream>
#include <vector>
int main()
{
std::ifstream file("Plop");
if (file)
{
/*
* Get the size of the file
*/
file.seekg(0,std::ios::end);
std::streampos length = file.tellg();
file.seekg(0,std::ios::beg);
/*
* Use a vector as the buffer.
* It is exception safe and will be tidied up correctly.
* This constructor creates a buffer of the correct length.
*
* Then read the whole file into the buffer.
*/
std::vector<char> buffer(length);
file.read(&buffer[0],length);
/*
* Create your string stream.
* Get the stringbuffer from the stream and set the vector as it source.
*/
std::stringstream localStream;
localStream.rdbuf()->pubsetbuf(&buffer[0],length);
/*
* Note the buffer is NOT copied, if it goes out of scope
* the stream will be reading from released memory.
*/
}
}
Run Code Online (Sandbox Code Playgroud)