【问题标题】:fseek now supports large filesfseek 现在支持大文件
【发布时间】:2011-07-07 19:25:12
【问题描述】:

现在看来 fseek,至少在我的实现中,自然支持大文件,没有 fseek64、lseek 或一些奇怪的编译器宏。

这是什么时候发生的?

#include <cstdio>
#include <cstdlib>
void writeF(const char*fname,size_t nItems){
  FILE *fp=NULL;
  if(NULL==(fp=fopen(fname,"w"))){
    fprintf(stderr,"\t-> problems opening file:%s\n",fname);
    exit(0);
  }
  for(size_t i=0;i<nItems;i++)
    fwrite(&i,sizeof(size_t),1,fp);
  fclose(fp);
}
void getIt(const char *fname,size_t offset,int whence,int nItems){
  size_t ary[nItems];
  FILE *fp = fopen(fname,"r");
  fseek(fp,offset*sizeof(size_t),whence);
  fread(ary,sizeof(size_t),nItems,fp);

  for(int i=0;i<nItems;i++)
    fprintf(stderr,"%lu\n",ary[i]);
  fclose(fp);
}


int main(){
  const char * fname = "temp.bin"; 
  writeF(fname,1000000000);//writefile
  getIt(fname,999999990,SEEK_SET,10);//get last 10 seek from start
  getIt(fname,-10,SEEK_END,10);//get last 10 seek from start
  return 0;
}

上面的代码以二进制 size_t 格式写入一个包含条目 1-10^9 的大文件。 然后写入最后 10 个条目,从文件开头查找,从文件末尾查找。

【问题讨论】:

  • 我以为 fseek 最多只能达到 2GB,但我在这里看不到 2GB 的文件。
  • @monkeyking - IOW,1000000000 = 1,000,000,000 和 999999990 = 999,999,990,这些都不 > 2GB
  • 另外,你没有提到平台... duh

标签: c++ 64-bit large-files fseek


【解决方案1】:

Linux x86-64 从一开始就支持大文件 (LFS);并且不需要任何特殊的宏等来启用它 - 传统的 fseek()) 和 LFS fseek64() 已经使用 64 位 off_t

Linux i386(32 位)通常默认为 32 位 off_t,否则会破坏大量应用程序 - 但您可以通过检查 _FILE_OFFSET_BITS 宏的值来测试您的环境中定义的内容。

有关 Linux 大文件支持的完整详细信息,请参阅 http://www.suse.de/~aj/linux_lfs.html

【讨论】:

    【解决方案2】:

    签名是

    int fseek ( FILE * stream, long int offset, int origin );
    

    所以范围取决于long 的大小。

    在某些系统上它是 32 位的,而您在处理大文件时遇到问题,而在其他系统上它是 64 位的。

    【讨论】:

      【解决方案3】:

      999999990 是一个普通的 int 并且完全适合 32 位。不过,我不相信你会侥幸逃脱:

      getIt(fname,99999999990LL,SEEK_SET,10);
      

      【讨论】:

        猜你喜欢
        • 2015-05-29
        • 1970-01-01
        • 1970-01-01
        • 2013-06-11
        • 1970-01-01
        • 2021-03-23
        • 2010-10-14
        • 2021-07-21
        • 2013-08-07
        相关资源
        最近更新 更多