C++使用ifstream从内存中读取数据

12

我有一些使用 ifstream 从文件中读取数据的代码,一切正常。

现在,我希望不修改任何代码的情况下,从内存中读取这些数据。事实上,我有一个包含数据的char *...

如何将我的char * 数据放入一个ifstream 中,而不实际读取文件?


可能是 [设置标准流使用的内部缓冲区(pubsetbuf)] (https://dev59.com/I3I_5IYBdhLWcg3wK_3E) 的重复。 - Ciro Santilli OurBigBook.com
5个回答

16

虽然使用std::istringstream(有时会错误地没有提及前导的i;这样的类确实存在,但更昂贵,因为它还设置了输出流)非常流行,但我认为值得指出的是,这将至少复制一次实际字符串(我怀疑大多数实现甚至会创建两个副本)。可以使用简单的流缓冲区避免创建任何副本:

struct membuf: std::streambuf {
    membuf(char* base, std::ptrdiff_t n) {
        this->setg(base, base, base + n);
    }
};
membuf sbuf(base, n);
std::istream in(&sbuf);

对于一个小内存区域,这种差异可能并不重要,尽管在那里节省分配的内存也是显著的。但对于大块的内存来说,这会产生很大的影响。


9
标准库提供了一个可读写的内存流istreamstd::stringstream
您需要适当地抽象您的代码,以便它接受一个通用的istream而不是一个ifstream,构造一个stringstream,将其填充到您的数据中并将其传递给函数。
例如:
const char* data = "Hello world";
std::stringstream str((std::string(data))); // all the parens are needed,
                                            // google "most vexing parse"

do_something_with_istream(str); // pass stream to your code

9

如果使用 ifstream& 的代码稍微更改一下,使用 istream&,那么您可以轻松地在 ifstreamistringstream 之间切换(用于从内存中读取数据):

void read_data(std::istream& in)
{
}

呼叫者:

std::istringstream in_stream(std::string("hello"));
read_data(in_stream);

std::ifstream in_file("file.txt");
read_data(in_file);

1

0
在我的项目中,我使用iostream的write()和read()方法,因为我将二进制数据写入stringstream。很抱歉,以下代码未经测试,可能存在语法错误(在办公室打字...;-),但类似这样的代码可以让您将数据写入内存、文件和其他地方(例如网络套接字):
void foo(std::iostream *mystream)
{
    mystream.write("Hello", 5);
    uint32_t i=5302523;
    mystream.write((char*) &i, sizeof i);
}

int main()
{
    // Write to memory. stringstream's write() and read() work binary
    std::stringstream memstream;
    foo(&memstream);

    // Write to file
    std::fstream f;
    try
    {
        f.open("file.dat");
        foo(&f);
    }
    catch (...)
    {
        // ...
    }

    if (f.is_open())
        f.close();

    return EXIT_SUCCESS;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接