fseek теперь поддерживает большие файлы - PullRequest
4 голосов
/ 07 июля 2011

Похоже, что теперь 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;
}

TheПриведенный выше код записывает большой файл с записями 1-10 ^ 9 в двоичном формате size_t.И затем записывает последние 10 записей, ища с начала файла и ища с конца файла.

Ответы [ 3 ]

1 голос
/ 07 июля 2011

Linux x86-64 имеет поддержку больших файлов (LFS) с самого первого дня; и не требует никаких специальных макросов и т. д. для его включения - как традиционные fseek()), так и LFS fseek64() уже используют 64-битные off_t.

Linux i386 (32-битный) обычно по умолчанию равен 32-битному off_t, так как в противном случае он сломал бы огромное количество приложений - но вы можете проверить то, что определено в вашей среде, проверив значение макроса _FILE_OFFSET_BITS.

См. http://www.suse.de/~aj/linux_lfs.html для полной информации о поддержке больших файлов в Linux.

1 голос
/ 08 июля 2011

Подпись

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

, поэтому диапазон зависит от размера long.

В некоторых системах он 32-разрядный, и у вас есть проблема с большими файламив других системах он 64-битный.

0 голосов
/ 07 июля 2011

999999990 - это обычный int, который идеально вписывается в 32 бита.Я не верю, что вам это сойдет с рук:

getIt(fname,99999999990LL,SEEK_SET,10);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...