【发布时间】:2010-07-20 00:20:19
【问题描述】:
好的,我一直在阅读 fread() [返回类型 size_t] 并看到了几篇关于大文件和其他一些问题的帖子 - 但我仍然遇到一些问题。该函数传入一个文件指针和一个 long long int。 lld 来自 main 我使用另一个函数来获取实际文件大小,即 6448619520 字节。
char *getBuffer(FILE *fptr, long long size) {
char *bfr;
size_t result;
printf("size of file in allocate buffer: %lld\n", size);
//size here is 6448619520
bfr = (char*) malloc(sizeof(char) * size);
if (bfr == NULL) {
printf("Error, malloc failed..\n");
exit(EXIT_FAILURE);
}
//positions fptr to offset location which is 0 here.
fseek(fptr, 0, SEEK_SET);
//read the entire input file into bfr
result = fread(bfr, sizeof(char), size, fptr);
printf("result = %lld\n", (long long) result);
if(result != size)
{
printf("File failed to read\n");
exit(5);
}
return (bfr);
}
我已经在 1-2gb 大小的文件上对其进行了测试,它工作正常,但是,当我在 6gb 文件上测试它时,没有任何内容被读入缓冲区。忽略其他结果,(重点关注结果的粗体),问题在于读取数据 bfr。这是我得到的一些结果。
文件的第一个是 735844352 字节 (700+MB)
root@redbox:/data/projects/C/stubs/# ./testrun -x 45004E00 -i /data/Helix2008R1.iso
图像文件是 /data/Helix2008R1.iso
十六进制字符串 = 45004E00
>文件总大小:735844352
获取缓冲区中的文件大小:735844352
结果 = 735844352
** 开始解析命令行十六进制值:45004E00
十六进制字符串的总字节数:4十六进制字符串搜索结果:
在字节位置找到十六进制字符串 45004E00:37441
在字节位置找到十六进制字符串 45004E00:524768
....
针对 6gb 文件运行 #2: root@redbox:/data/projects/C/stubs/# ./testrun -x BF1B0650 -i /data/images/sixgbimage.img
图像文件是/data/images/sixgbimage.img
十六进制字符串 = BF1B0650
文件总大小:6448619520
分配缓冲区中的文件大小:6448619520
结果 = 0
文件读取失败
我仍然不确定为什么它在大文件而不是小文件上失败,这是一个 >4gb 的问题。我正在使用以下内容:
/* Support Large File Use */
#define _LARGEFILE_SOURCE 1
#define _LARGEFILE64_SOURCE 1
#define _FILE_OFFSET_BITS 64
顺便说一句,我使用的是 ubuntu 9.10 机器(2.6.x 内核)。 tia。
【问题讨论】:
-
它是 32 位函数吗?使用 32 位,您只能访问 4 GB 的字节可寻址内存。如果您无法访问超过 4GB 的任何内容,我怀疑这至少是部分原因。
-
是的,它是一个 32 位函数。我猜这可能是一个 >4gb 的问题,仍在研究如何解决这个问题..
-
我读对了吗?您想一次将一个 6GB 的文件直接读入 RAM 吗?不要那样做,即使你认为你有足够的内存。像 sarnold 建议的那样使用 mmap。
-
还有 32 位功能?这是否意味着您使用的是 32 位操作系统?在那种情况下你不能 fread() 6Gb,没有足够的内存地址空间。
-
是的,在 32 位操作系统上 - 明白了,我现在知道这是不可能的 :) 必须一次读取小块,比如每 512 个字节或一个扇区。
标签: c