c处理大文件

c处理大文件,c,large-files,C,Large Files,我需要解析一个大小可能有很多GB的文件。我想用C语言来完成这项工作。有人能建议一些方法来完成这项工作吗 我需要打开并解析的文件是一个硬盘转储文件,它是我从mac电脑的硬盘上获取的。然而,我计划在64位Ubuntu 10.04中运行我的程序。另外,考虑到文件大小较大,方法越优化越好。根据不同的情况,可能会有一些免费的商业工具包来创建文件格式的解析器。我认为你所面临的真正问题是如何“处理”几GB的数据 是否希望所有数据同时存储在内存中? 一种方法是在不使用时,将部分文件以临时文件的形式写入磁盘。简单

我需要解析一个大小可能有很多GB的文件。我想用C语言来完成这项工作。有人能建议一些方法来完成这项工作吗

我需要打开并解析的文件是一个硬盘转储文件,它是我从mac电脑的硬盘上获取的。然而,我计划在64位Ubuntu 10.04中运行我的程序。另外,考虑到文件大小较大,方法越优化越好。

根据不同的情况,可能会有一些免费的商业工具包来创建文件格式的解析器。我认为你所面临的真正问题是如何“处理”几GB的数据

是否希望所有数据同时存储在内存中?

一种方法是在不使用时,将部分文件以临时文件的形式写入磁盘。简单的fread/fwrite结构,以及一些巧妙的ref计数的“按需”加载和编写可以做到这一点,

假设您使用的是linux/bsd/mac/notwindows 64位系统(说真的,现在谁不是呢?),性能非常好。它本质上允许您将整个文件映射到进程的地址空间,并让内核为您执行缓存/分页


如果你必须使用windows,这是相同的概念,但由Redmond的友好人士制作。请注意,对于其中任何一个,您都希望在64位系统上运行,因为在32位系统上可以映射的绝对最大文件是~4GB。

在*nix和Windows上,都有I/O例程的扩展,这些扩展涉及支持大于2GB或4GB大小的文件大小。当然,底层文件系统也必须支持这么大的文件。在Windows上,NTFS有,但FAT没有。这通常被称为“大文件支持”


对于这些目的来说,最关键的两个例程是
fseek()
ftell()
,这样您就可以对整个文件进行随机访问。否则,普通的
fopen()
fread()
和朋友可以顺序访问任何大小的文件,只要底层操作系统和stdio实现支持大文件。

除了RBerteig和Matt的答案外:

如果您正确且谨慎地为所有用户启用64位IO支持 项目中的文件(方法为systemn 依赖)如果 我想用正确的类型<代码>关闭\u t应该是正确的 选择文件指针的位置

如果所有其他方法都失败,请使用正确的C99类型,如果您选择 关于类型宽度的假设。使用
int
long
是错误的 几乎总是做错事,他们太多了 编译器/平台相关。如果需要,请使用
int64\u t
(或
int\u fast64\u t

不必这样。)

为所有相关源(最好是整个项目)定义宏
-D\u FILE\u OFFSET\u BITS=64
\Define\u FILE\u OFFSET\u BITS 64
。此公共宏由几个公共生成系统自动提供。然后在API需要的地方使用
off\t
(现在是64位)。

C打开文件的函数允许您一次读取一小部分文件。你不需要一次将整个文件放入内存。我不一定要在内存中打开整个文件,但如何访问偏移量高于最大c整数的数据字节?@romejoe,快速谷歌搜索(man-fseek)显示偏移量是长的,而不是整数,所以你应该能够访问2GB。fseek还接受第三个参数SEEK\u CUR,它将请求的偏移量添加到当前位置。还有用于64位偏移量的fseeko。@atk:在许多机器上,long是64位的,您可以读取的文件比2GB大一点@romejoe:INT_MAX==LONG_MAX吗?你的机器上有“long long”(C99)吗?@Jonthan Leffler,没错。我更想回答reomejoe关于超过最大整数的问题,这意味着他使用的是32位系统。-1表示“现在谁不是?”约64位。我敢打赌95-99%的真实世界(与游戏玩家kiddie world相反)的PC/工作站是32位的。内存映射很好,但考虑到OP的简单问题,我认为他会寻找最基本的接口,性能也没有提到。还要注意的是,即使在64位系统上,文件也可能比映射文件大,因为当前一代64位CPU实际上只有48位地址空间。128TB左右的容量现在看起来可能很大,但也有这样大小的磁盘阵列…@R:我怀疑他是否打算在普通PC上读取大型文件。很可能这是一台服务器。这个答案相当误导。仅仅使用正确的类型是不够的;您需要使用能够处理偏移的函数。在大多数unix系统(当然在Linux上)上,默认编译环境的
off\t
定义为
long
,因此在32位机器上,它将仅为32位。您通常需要使用
-D_FILE_OFFSET_BITS=64
构建整个程序,并使用
fseeko
ftello
函数来获得正常的行为-当然,还需要使用
off_t
类型作为偏移变量。顺便说一句,即使您从未执行过任何搜索,如果没有大文件支持,IO在大于2gb的文件上也会失败。@R:您读过我答案的第一句话了吗?显然,我所说的其余部分是不够的,但这已经在RBerteig的回答中给出了。也许我的措辞不够好,我不是英语母语,但你会怎么说这样的话呢?嗯,这是误导,因为它没有提到如何启用64位IO。只使用
off\t
而不定义正确的宏是行不通的。@bdonlan:正如你在对马特的回答的评论中提到的,没有一般的规则可以这样做。但我将尝试重新制定我的答案,使之更清楚。这只适用于POSIX系统。