c – 可以打开小的ASCII文件,但不是大二进制文件?

前端之家收集整理的这篇文章主要介绍了c – 可以打开小的ASCII文件,但不是大二进制文件?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用下面的代码Windows上的MSVC中打开一个大的(5.1GB)二进制文件.机器有大量的RAM.问题是长度被检索为零.但是,当我将file_path更改为较小的ASCII文件时,代码工作正常.

为什么我不能加载大二进制文件?我喜欢这种方法,因为我想要一个指向文件内容的指针.

FILE * pFile;
uint64_t lSize;
char * buffer;
size_t result;

pFile = fopen(file_path,"rb");
if (pFile == NULL) { 
    fputs("File error",stderr); exit(1); 
}

// obtain file size:
fseek(pFile,SEEK_END);
lSize = ftell(pFile);                                // RETURNS ZERO
rewind(pFile);

// allocate memory to contain the whole file:
buffer = (char*)malloc(sizeof(char)*lSize);
if (buffer == NULL) {
    fputs("Memory error",stderr); exit(2); 
}

// copy the file into the buffer:
result = fread(buffer,1,lSize,pFile);             // RETURNS ZERO TOO
if (result != lSize) {                               // THIS FAILS
    fputs("Reading error",stderr); exit(3); 
}

/* the whole file is now loaded in the memory buffer. */

它不是文件的权限或任何东西,他们是罚款.

解决方法

如果您分配了5,1 GB,最好确保您已经编译了64位的代码,并在64位Windows版本上运行. Ohterwhise,内存 address space is limited到最大3 GB,32位Windows和 4 GB with 32 bits code on a 64 bits Windows.

顺便说一下,ftell()返回一个签名的长.您必须检查这里是否有错误(例如,如果操作系统允许较大的文件大小,则会出现溢出),以使该值不为-1.

编辑:

请注意,with MSVC,long will currently be即使编译为64位也是32位数.这意味着如果文件大小在2GB以下(因为符号),ftell()会给你一个有意义的结果.

您可以使用非便携式操作系统特定的WinAPI功能GetFileSizeEx()获取带有64位数的大型文件的大小.

malloc()需要一个size_t,这是一个unsigned 64 bit number.所以在这方面你是安全的.

另一种方法是使用file mapping.

第二编辑

我看着你对大小收到的价值的编辑,这与我预期的不一样.我可以在我的系统上重现错误,并且具有不为空的大小,但它比文件大得多.

this CERT security recommendation看,fseek()与SEEK_END相结合的标准提供的担保是不合适的,这使得这是一个非常不安全的做法.

所以让我们重申一下:获取大小的最简单的方法是在Windows上使用本机OS功能,即GetFileSizeEx().在64位窗口中有一个解决方法:使用_fseeki64()和_ftelli64():

...
if (_fseeki64(pFile,SEEK_END)) {
    fputs("File seek error",stderr); 
    return (1);
}
lSize = _ftelli64(pFile);                            // RETURNS EXACT SIZE
...

这一点很好(初始问题似乎与不够大的返回类型相关联).但是请记住,这是一个解决方法,我担心可能会有其他错误条件可能导致CERT报告的漏洞.

猜你在找的C&C++相关文章