c - 是否可以在不将文件加载到内存的情况下读取文件?

标签 c file memory

我想读取一个文件,但它太大了,无法将它完全加载到内存中。

有没有办法不用加载到内存就可以读取它?或者有更好的解决方案?

最佳答案

I want to read a file but it is too big to load it completely into memory.

请注意 - 在实践中 - filesabstraction (所以不知何故是一种幻觉)由你提供 operating system通过 file systems .阅读Operating Systems: Three Easy Pieces (可免费下载)以了解有关操作系统的更多信息。文件可能很大(即使其中大部分很小),例如当前的笔记本电脑或台式机上有数十 GB(服务器上有许多 terabytes,甚至更多)。

你没有定义什么是内存,C11标准n1570以不同的方式使用该词,在 §3.14 中谈到内存位置,在 §7.22.3 中谈到内存管理功能...

在实践中,一个 process有它的virtual address space , 与 virtual memory 有关.

关于很多operating systems -特别是 Linux 和 POSIX- 您可以使用 mmap(2) 更改虚拟地址空间及相关system calls , 你可以使用 memory-mapped files .

Is there a way to read it without loading it into memory?

当然,您可以读取和写入某些文件的部分块(例如使用 freadfwritefseek 或较低级别的系统调用 read(2)write(2)lseek(2) 、 ...)。出于性能原因,最好使用大缓冲区(至少几千字节)。在实践中,大多数checksums (或 cryptographic hash functions )可以在非常长的数据流上按 block 计算。

许多库都是在这些原语之上构建的(按 block 进行直接 IO)。例如 sqlite数据库库能够处理 many terabytes 的数据库文件(超过可用 RAM)。你可以使用 RDBMS (它们是用 C 或 C++ 编码的软件)

因此,您当然可以处理大于可用 RAM 的文件,并按 block (或“记录”)读取或写入它们,至少从 1960 年代开始就是如此。我什至会直觉地说,文件(通常)可以比 RAM 大得多,但比单个磁盘小(但是,即使这并不总是正确的;一些文件系统能够跨越多个物理磁盘,例如使用 LVM技术)。

(在我的 Linux 桌面上有 32GB 的内存,最大的文件有 69GB,在 ext4 文件系统上有 669G 的可用空间和 780G 的总空间,我过去确实有超过 100GB 的文件)

您可能会发现值得使用一些数据库,例如 sqlite (或者是一些 RDBMS 的客户端,如 PostGreSQL 等...),或者您可能对索引文件的库感兴趣,如 gdbm .当然你也可以直接进行 I/O 操作(例如 fseek 然后 fread 或者 fwrite,或者 lseek 然后readwrite,或 pread(2)pwrite ...)。

关于c - 是否可以在不将文件加载到内存的情况下读取文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48065547/

相关文章:

c - sscanf 返回奇怪的错误

java - 无法访问原始文件夹中的文件

c - 哪一位是整数的地址?

c - 编译器在布局内存时是否考虑了内核内存空间?

c++ - 从其他 4 个中找出纹理坐标?

c - 查看使用指针创建的动态变量?

arrays - 将文件行存储到数组中

ruby - 如何删除 Ruby 文件的最后一行?

java - 内存不足且 CPU 消耗低

c - 如何读取数组直到新行 '\n'?