为了提高从文件读取的性能,我试图将大(几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 …Run Code Online (Sandbox Code Playgroud) 我找不到任何现成的东西,所以我想出了:
class membuf : public basic_streambuf<char>
{
public:
membuf(char* p, size_t n) {
setg(p, p, p + n);
setp(p, p + n);
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
char *mybuffer;
size_t length;
// ... allocate "mybuffer", put data into it, set "length"
membuf mb(mybuffer, length);
istream reader(&mb);
// use "reader"
Run Code Online (Sandbox Code Playgroud)
我知道stringstream,但它似乎无法使用给定长度的二进制数据.
我在这里发明了自己的轮子吗?
编辑
我的问题如下:Martin York在此声称,这个,并且这个答案可以stringstream通过使用basic_stringbuf::pubsetbuf这样的方式从一些内存中读取:
char buffer[] = "123";
istringstream in;
in.rdbuf()->pubsetbuf(buffer, sizeof(buffer)); // calls basic_stringbuf::setbuf
int num;
in >> num; // reads 123
Run Code Online (Sandbox Code Playgroud)
不幸的是,我挖掘了整个标准,无法确定它在哪里工作.我看到的只是实现定义.实际上在微软的实现上(也许在其他人的实现上),这个调用没有任何效果.
以下是我在上一篇C++ 0x草案中找到的相关引文.对于basic_streambuf::setbuf[streambuf.virt.buffer]:
1 效果:以本条款(27.8.1.4,27.9.1.5)中从basic_streambuf派生的每个类别单独定义的方式影响流缓冲.
2 默认行为: 什么都不做.返回此.
但是在派生类中,它似乎保留了行为实现定义.因为basic_stringbuf::setbuf它说[stringbuf.virtuals]:
1 效果: 实现定义,但setbuf(0,0)无效.
因为basic_filebuf::setbuf它说[filebuf.virtuals]:
12 效果:如果setbuf(0,0)[...],则流变为无缓冲.否则结果是实现定义的."无缓冲"[...]
就是这样.所以我看到它,一个有效的实现可以完全忽略这些调用(对于非null参数).
我错了吗?这个标准的正确解释是什么?C++ 98/03/0x有相同的保证吗?您是否有更多关于上述代码的哪些实现以及不适用的实现的统计信息?如何basic_streambuf::setbuf使用?
我有一个内存块(不透明),我想通过他们的C++适配器存储在mySQL的Blob中.适配器需要一个istream:
virtual void setBlob(unsigned int parameterIndex, std::istream * blob) = 0;
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:如何从这个内存块创建一个std :: istream(键入为char*).它不是一个字符串,因为它不是以空值终止的(但我知道它的长度当然).
如果没有复制我的内存块,例如在std :: string中,我找不到一种方法.我认为这有点浪费.这样的东西不起作用:
std::streambuf istringbuf(blockPtr, blockLength);
std::istringstream tmp_blob(&istringbuf);
Run Code Online (Sandbox Code Playgroud)
因为std :: streambuf没有这样的构造函数.我看到了以下建议.
std:: istringstream tmp_blob;
tmp_blob.rdbuf()->pubsetbuf(blockPtr, blockLength);
Run Code Online (Sandbox Code Playgroud)
这是正确的方法吗?
我在VC++中编写DLL,我需要使用外部文本文件.我现在有类似的东西:
ifstream file;
string line;
file.open("C:\\Users\\Me\\Desktop\\textfile.txt");
getline(file,line);
file.close();
Run Code Online (Sandbox Code Playgroud)
我知道我可以在Resources中拥有这个文件吗?
我通过转到"ResourceView" - >"添加资源" - >"导入"添加了我的文本文件.我选择了我的文本文件并创建了自定义资源类型.
如何访问此文件以与上面的代码类似地使用?我有Resource.h但我应该怎么做呢?我也可以编辑我的资源文本文件吗?
c++ ×4
c++11 ×1
dll ×1
memory ×1
memorystream ×1
optimization ×1
resource-dll ×1
stream ×1
streambuf ×1
stringstream ×1
visual-c++ ×1