开发者

fseek now supports large files

It appears that fseek now, at least in my implementation, supports large files naturally without fseek64, lseek or some strange compiler macro.

When did this happen?

#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;
}

The code above writes a big file with the entries 1-10^9 in binary size_t format. And then writes the last 10 entries, seeking from the beginning of the file, and seek from the end of file.


Linux x86-64 has had large file support (LFS) from pretty much day one; and doesn't require any special macros etc to enable it - both traditional fseek()) and LFS fseek64() already use a 64bit off_t.

Linux i386 (32bit) typically defaults to 32-bit off_t as otherwise it would break a huge number of applications - but you can test what is defined in your environment by checking the value of the _FILE_OFFSET_BITS macro.

See http://www.suse.de/~aj/linux_lfs.html for full details on Linux large file support.


The signature is

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

so the range depends on the size of long.

On some systems it is 32-bit, and you have a problem with large files, on other systems it is 64-bit.


999999990 is a normal int and fits perfectly into 32 bits. I don't believe that you'd get away with this though:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜