在 Lion 操作系统上,当长度大于2G时,Fread 无法读取。

3
自从Macosx Lion版本开始,fread函数不再支持读取长度大于2G(即int size, 2'147'483'648字节)的文件。而在之前的Macosx Snow Leopard版本中这个函数一直是正常工作的。
我写了一个测试程序来验证这一点:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
FILE   *fin = NULL, *fout = NULL;
char   *ptr = NULL;
size_t len;
fpos_t flen;

if (!(fin = fopen(argv[1], "rb")))
{
    printf("The input file: %s could not be opened\n", argv[1]);
    return -1;
}
if ((fout = fopen(argv[2], "rb")))
{
    printf("The output file %s already exist\n", argv[2]);
    fclose(fin);
    return -1;
}
if (!(fout = fopen(argv[2],"wb")))
{
    printf("Cannot write on output file %s\n", argv[2]);
    fclose(fin);
    return -1;
}

fseek(fin, 0, SEEK_END);
fgetpos(fin, &flen);
len = flen;
printf("Input file length : %zd\n", len);
fseek(fin, 0, SEEK_SET);

if (!(ptr = malloc(len))) 
{
    printf("Canot allocate %zd bytes\n", len);
    fclose(fin);
    fclose(fout);
    return -1;
}
if (fread(ptr, sizeof(char), len, fin) != len)
{
    printf("Cannot read file\n");
    fclose(fin);
    fclose(fout);
    free(ptr);
    return -1;
}
fclose(fin);
if (fwrite(ptr, sizeof(char), len, fout) != len) 
{
    printf("Cannot write file\n");
    fclose(fout);
    free(ptr);
    return -1;
}
free(ptr);
fclose(fout);

return 1;
}

只需运行:

  • ./pgm inputfile outputfile
  • openssl sha inputfile
  • openssl sha outputfile

没有错误。 两个文件的长度相同。 两个指纹不相同。 (指针已经分配并写在输出文件中) 只有fread有问题,fwrite没有问题。

我不明白问题出在哪里。

我只看到这个程序(我不知道苹果是否在Lion上使用它),r变量定义为int。 http://www.opensource.apple.com/source/Libc/Libc-186/stdio.subproj/fread.c

谢谢回答。


2
OSX是32位还是64位的?如果是32位的话,就没有理由期望能够读取超过2GB的数据,甚至无法在内存中创建如此大的对象。 - R.. GitHub STOP HELPING ICE
3个回答

1

在我的MacOS X Lion(10.7.2)上,XCode 4.2可以正常工作。可执行程序是64位程序。你应该确保你的程序也是64位的。

$ make 2gb
/usr/bin/gcc -g -std=c99 -Wall -Wextra 2gb.c -o 2gb
2gb.c:5: warning: unused parameter ‘argc’
$ file 2gb
2gb: Mach-O 64-bit executable x86_64
$ dd if=/dev/zero of=input bs=1m count=3072
./2g3072+0 records in
3072+0 records out
3221225472 bytes transferred in 42.940363 secs (75016261 bytes/sec)
$ ls -l input
./2gb -rw-r--r--  1 jleffler  staff  3221225472 Oct 29 00:48 input
$ ./2gb input output
Input file length : 3221225472
$ openssl sha input
SHA(input)= c93bf6713a90e34554311f0a9e43cfd1f153475a
$ openssl sha output
SHA(output)= c93bf6713a90e34554311f0a9e43cfd1f153475a
$ ls -l input output
-rw-r--r--  1 jleffler  staff  3221225472 Oct 29 00:48 input
-rw-r--r--  1 jleffler  staff  3221225472 Oct 29 00:49 output
$ rm input output
$ /usr/bin/gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$

当被强制编译为32位时:

$ rm 2gb
$ make CC='/usr/bin/gcc -m32' 2gb
/usr/bin/gcc -m32 -g -std=c99 -Wall -Wextra 2gb.c -o 2gb
2gb.c:5: warning: unused parameter ‘argc’
$ dd if=/dev/zero of=input bs=1m count=3072
3072+0 records in
3072+0 records out
3221225472 bytes transferred in 38.326753 secs (84046397 bytes/sec)
$ ./2gb input output
Input file length : 0
$ ls -l input
-rw-r--r--  1 jleffler  staff  3221225472 Oct 29 00:57 input
$ 

在这里创建测试文件时,/dev/zero 是一个不好的选择。因为非常大的 malloc 调用将从内核中拉取零页,如果 fread 出现问题,您将会测试一个由零组成的文件与一个由零组成的内存空间。 - Zan Lynx

1

看起来你没有以64位模式编译。查找你正在使用的编译器的命令行参数或选项。为了确保你在正确的模式下编译,可以使用printf("%d\n", sizeof(int));,看看它是否显示了你期望的结果。


0

printf("%d\n", sizeof(int)); gcc -Wall Typ.c -o Typ 警告:格式‘%d’期望类型为‘int’,但参数2的类型为‘long unsigned int’ 警告:格式‘%d’期望类型为‘int’,但参数2的类型为‘long --> 4

谢谢Jonathan。

我使用的是10.7.2和xcode 4.2

gcc --version i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (基于Apple Inc. build 5658) (LLVM build 2336.1.00)

我执行了gcc TestFile.c -o TestFile.o 甚至完全按照您的方式: /usr/bin/gcc -g -std=c99 -Wall -Wextra 2gb.c -o 2gb 然后我加上了-m64

但我又得到了两个不同的指纹。

xcode 3.6.2已被删除,使用sudo /Library/uninstall-devtools --mode=all 然后安装了xcode 4.2。

我在新创建的另一个用户上运行程序(可能是因为$path),结果还是一样。

我不明白。


苹果团队在报告此错误后的回复

你好,Stéphane,

这是对Bug ID#10376104的跟进。经过进一步调查,确定这是一个已知问题,目前正在由工程师进行调查。此问题已在我们的错误数据库中以原始Bug ID#6434977的形式进行了记录。用于跟踪此重复问题的原始错误编号可以在您的错误报告的“相关问题”部分中找到。

感谢您提交此错误报告。我们真诚地感谢您协助我们发现和隔离错误。

此致

开发人员错误报告团队 苹果全球开发者关系


我创建了一个新的分区,安装了Lion系统,升级至Lion 10.7.2版本,之后安装Xcode 4.2版本。但是,问题又出现了(真的很难以置信)……因此,我准备向苹果公司报告这个故障。我的机器型号是2010年9月发布的Mac Pro 6核心版。 - Stephane
苹果团队在报告此漏洞后进行了回应-请参见上文(超过556个字符)。 - Stephane
终于解决了!是的,他们做到了!虽然花费了超过两年的时间,但这个问题现在已经得到解决。(在最新的Mavericks系统中) - Stephane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接