无法打开存在的二进制文件

Unable to open binary file that exists

我无法打开该特定文件(从 here 获取,它在 gist.tar.gz 中),但是我可以打开查询文件并正确读取它。怎么了?也许问题在于文件对我来说太大了?但我认为如果是这种情况,我可以打开它然后收到 bad_alloc 或其他东西。

事情是这样的:

samaras@samaras-A15:~/parallel/rkd_forest/code$ ./rkd_sam 
I/O error : Unable to open the file ../Datasets/gist/gist_base.fvecs
samaras@samaras-A15:~/parallel/rkd_forest/code$ cd ../Datasets/gist/
samaras@samaras-A15:~/parallel/rkd_forest/Datasets/gist$ ls
gist_base.fvecs  gist_groundtruth.ivecs  gist_learn.fvecs  gist_query.fvecs

这是我的代码(应该没问题):

FILE* fid;
fid = fopen(filename, "rb");
if (!fid)
  printf("I/O error : Unable to open the file %s\n", filename);

文件的权限如下:

它的大小是 3.8 GB(3,844,000,000 字节),我知道这个数据集是

因此我 到另一台机器,但我遇到了同样的问题。

那里的内存(它是 64 位,而我的电脑运行在 32 位):

gsamaras@geomcomp:~/Desktop/code$ free -mt
             total       used       free     shared    buffers     cached
Mem:          3949       3842        106          0        173       3186
-/+ buffers/cache:        483       3466
Swap:        10867         59      10808
Total:       14816       3901      10914

std::cerr << "Error: " << strerror(errno) << std::endl;

给予

Error: Value too large for defined data type


printf("|%s|\n", filename);

给予

|../Datasets/gist/gist_base.fvecs|

值取自 cmd 和我正在执行的代码:

readDivisionSpacefvecs<FT>(test, N, D, argv[8]); // in main()

然后

void readDivisionSpacefvecs(Division_Euclidean_space<T>& ds, int& N, int& D, char* filename) {
  FILE* fid;
  fid = fopen(filename, "rb");
  printf("|%s|\n", filename);
  if (!fid) {
    printf("I/O error : Unable to open the file %s\n", filename);
    std::cerr << "Error: " << strerror(errno) << std::endl;
  }
  ...
}

我也尝试移动包含数据集的文件夹,但我得到了相同的结果!

似乎程序试图打开当前目录 (code) 中的文件,而文件在另一个目录中 (Datasets/gist'). You did not provide the value of thefilename` 变量,但它应该包含完整的正确工作的文件路径。

你可以试试

cd ../Datasets/gist/
../../code/rkd_sam

如果 filename 只包含没有任何路径的基本名称,这应该有效。

fopen() 而言,文件的大小根本无关紧要。

你得到的错误是EOVERFLOW,也就是你读到the open manual page的意思是

pathname refers to a regular file that is too large to be opened. The usual scenario here is that an application compiled on a 32-bit platform without -D_FILE_OFFSET_BITS=64 tried to open a file whose size exceeds (1<<31)-1 bytes; see also O_LARGEFILE above. This is the error specified by POSIX.1-2001; in kernels before 2.6.24, Linux gave the error EFBIG for this case.

这意味着您在 32 位平台上并尝试打开一个太大而无需特殊考虑即可处理的文件。

要么使用 -D_FILE_OFFSET_BITS=64 重新编译您的程序,要么使用带有 O_LARGEFILE 标志的 open 调用。