【问题标题】:How to read from RAM?如何从 RAM 中读取?
【发布时间】:2019-12-02 17:32:03
【问题描述】:

我需要做什么?

我需要从 RAM 中读取文件

我是怎么做到的?

我使用std::istream,因为它知道如何从缓冲区中读取。所以,有一种方法知道如何读取文件大小(根据这个 SO 答案https://stackoverflow.com/a/6039648/5709159

long getFileSize(const std::string &filename)
{
    struct stat stat_buf{};
    int rc = stat(filename.c_str(), &stat_buf);
    return rc == 0 ? stat_buf.st_size : -1;
}

然后我使用 membuf 将字节从文件复制到缓冲区(根据这个 SO 回答 https://stackoverflow.com/a/13586356/5709159

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

完整实现如下所示

long size = getFileSize(filename);
membuf sbuf(0, size);
std::istream file(&sbuf);

但是,我现在确定 sbuf(0, size);0 是在正确的位置......

所以,问题是 - 如何设置 membuf 的大小合适?

【问题讨论】:

  • 你的问题很混乱。
  • @Slava 为什么?我只是想知道是否像我一样设置 membuf,可以吗?
  • 因为如果它意味着什么,它的含义与问题本身完全不同。你用过在线翻译吗?
  • @Slava 不,但我也不是母语人士......我改变了问题的标题......
  • 第一个参数是缓冲区的开始。您设置为 0,这意味着它将尝试从 RAM 中的零地址读取。那是你要的吗?在大多数操作系统上,它会导致崩溃。

标签: c++ file buffer istream


【解决方案1】:

选项 1

扩展您问题中的代码:

long size = getFileSize(filename);
std::vector<char> buffer(size);
// here fill the buffer with data
membuf sbuf(buffer.data(), buffer.size());
std::istream file_from_ram(&sbuf);

如果您想用某个文件的内容填充缓冲区,请执行以下操作:

std::istream original_file("filename.dat");
original_file.read(buffer.data(), size);

注意:这个方法有问题。首先,正如@andrew-henle 在 cmets 中提到的,off_t 类型的文件大小可能无法填充到long。其次,此方法存在 TOCTOU(检查时间 -- 使用时间)问题:如果在调用 getFileSize 和读取文件之间文件大小发生变化,您可能会遇到麻烦。

选项 2

改用std::istringstream

std::string buffer;
// here fill the string with data
std::istringstream file_from_ram(buffer);

如果您想用某个文件的内容填充缓冲区,请执行以下操作(来自https://stackoverflow.com/a/116220/4451432):

std::ifstream original_file("filename.dat");

std::istringstream file_from_ram;
file_from_ram << original_file.rdbuf();
// Now you can read from file_from_ram

【讨论】:

  • 实际上您提供的第一个选项我已经完成了,但是检查第二个选项的执行时间很有趣,并且需要*2更多时间...我希望这是由于方法每次调用方法都会为std::string 分配内存,其中std::vector 我在.h 文件中删除并调整它的大小......所以,第一个选项更快(正如我测试的那样)。而且我得到了错误租用file_from_ram &lt;&lt; original_file.rdbuf(); 并且在我将std::istringstream 更改为std::stringstream 之后它可以工作。
【解决方案2】:

据我了解您的问题,您想读取文件。

您需要了解程序的每个变量都存储在您的内存中。因此,要“从 ram 读取文件”,您只需按照习惯读取文件即可。

如果问题在于将文件存储在您的 ram 中以便稍后在另一个程序中使用它,那么它就是不正确的。从需要它的程序中读取文件。

【讨论】:

  • 那么,你怎么解释这个答案stackoverflow.com/a/13586356/5709159
  • 您发送的答案是关于效率的。由于可以将整个文件存储为 C 风格的 char 指针,因此它显然会比存储 std::istream 类占用更少的内存。如果你真的想这样做,你应该看看fopengetline
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 2012-08-15
相关资源
最近更新 更多