【问题标题】:Dynamic allocation of file data in C++C++中文件数据的动态分配
【发布时间】:2016-05-10 18:22:30
【问题描述】:

坦率地说,我有一个任务非常含糊地说,

“如果文件存在,则单参数构造函数为文件中包含的记录数分配内存,并将它们复制到内存中。”

现在,在考虑这条指令时,我似乎要分配动态内存 /before/ 复制数据,这在原则上似乎是不可能的。

要动态分配内存,据我所知,您需要在运行时定义要保留的块大小。

鉴于文件大小或“条目”数量未知,怎么可能分配这么多内存?这个概念不是违背了动态分配的目的吗?

明智的解决方案,似乎唯一的选择是解析整个文件,确定大小,然后分配适当数量的内存,然后再次读取文件,将数据复制到分配的内存中。

鉴于这必须是任何读取文件数据的程序中的常见操作,我想知道:将文件加载到 RAM 中的正确或最有效的方法是什么?

读取一次以确定大小,然后再次复制的概念似乎非常低效。我认为有一种方法可以跳转到文件末尾以确定最大长度,这将使处理过程更快。或者也许使用静态缓冲区并将其以块的形式加载到 RAM?

是否可以读取所有数据,然后使用移动运算符将其移动到动态内存中?或者使用某种链接列表可能更有效?

【问题讨论】:

  • 如果不查看示例文件的内容,很难提出任何有用的建议。
  • @RSahu 这只是一个文本文件。
  • @RSahu 字符长度未知。
  • 如果记录大小是可变的,并且您必须预先分配所有内存,那么除了有效读取文件内容两次之外,别无他法。

标签: c++ file fstream move-semantics dynamic-allocation


【解决方案1】:

最有效的方法是让操作系统将文件映射到内存。在您的操作系统 API 中搜索“mmap”或“内存映射”。

另一种方法是寻找文件末尾并获取位置(tellg())。这是文件的大小。在动态内存中分配一个数组或创建一个std::vector,至少保留此数量的空间。

某些操作系统具有 API,您可以调用该 API 来获取文件的大小(无需搜索到最后)。您可以使用这种方法,然后动态分配内存或使用std::vector<char>

如果文件不适合内存,您需要制定一个计划。

如果您需要将整个文件读入内存,您可以使用istream::read 使用文件长度。

【讨论】:

  • 您的第二段是大多数人对此的看法,当然我也是这样做的。只需telling 文件的大小不需要任何分配。
【解决方案2】:

这完全取决于文件格式。存储记录的一种方法是首先写入文件中存储了多少记录。如果您有两个电话号码,您的文件可能如下所示:

2
Jon
555-123
Mary
555-456

在这种情况下,解决方案很简单:

// ...
is >> count;
record_type *record = new record_type[count];
for ( int i = 0; i < count; ++i )
  is >> record[i].name >> record[i].number; // stream checks omitted
// ...

如果文件中没有存储记录的数量(我不会这样做),你将不得不先统计它们,然后使用上面的解决方案:

// ...
int count = 0;
std::string dummy;
while ( is >> dummy >> dummy )
  ++count;
is.clear();
is.seekg( 0 );
// ...

第二种情况的第二种解决方案是编写一个动态容器(我假设您不允许使用标准容器)并在阅读时推送记录:

// ...
list_type list;
record_type r;
while ( is >> r.name >> r.number )
  list.push_back( r );
// ...

解决方案按复杂性排序。上面的例子我没有编译。

【讨论】:

    猜你喜欢
    • 2012-04-18
    • 2017-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2014-08-19
    相关资源
    最近更新 更多