【问题标题】:c++ use ifstream from memoryc ++使用内存中的ifstream
【发布时间】:2012-11-15 02:50:52
【问题描述】:

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

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

如何在不有效读取文件的情况下将我的char * 数据放入ifstream

【问题讨论】:

标签: c++ ifstream memcpy


【解决方案1】:

虽然使用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);

对于一小块内存,差异可能无关紧要,尽管节省的分配在那里也很明显。对于大块内存,它会产生重大影响。

【讨论】:

    【解决方案2】:

    如果使用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);
    

    【讨论】:

      【解决方案3】:

      标准库提供了一个内存中的istream,它也是可写的:std::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
      

      【讨论】:

        【解决方案4】:

        您可能正在搜索字符串流。 http://www.cplusplus.com/reference/sstream/stringstream/。我以前只用过一次,已经很久了,但基本上你可以从内存中的某个位置流式传输。

        【讨论】:

          【解决方案5】:

          在我的项目中,我使用 iostream 的 write() 和 read() 方法,因为我将二进制数据写入字符串流。抱歉,以下代码未经测试,可能存在语法错误(从办公室打字... ;-),但类似这样的内容允许您写入内存、文件和其他地方(例如网络套接字):

          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;
          }
          

          【讨论】:

            猜你喜欢
            • 2014-11-03
            • 2023-04-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多