ネットで1000万行のファイルを読み込ませて逆順にしたいとか言うのを(perlで)みたので、Cで1500万行近くまで対応してみた。
やり方としては一回EOFまでfputs回して、ftellで位置情報を配列に記録。
配列の逆から位置情報読み込んでfseekで移動を繰り返す。
記録時間が最初かかるけど、配列の大きさからビビっていたほどはメモリも消費しない。
(1400万行3.1GBの文字ファイルに対し、4GBメモリの0.6%)
#include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { for(int i = 1; i < argc; i++) { FILE *fp; if((fp = fopen(argv[i],"r"))) { const int BUF = 1024 * 4; char s[BUF]; long *fpos; int k = 0; puts(argv[i]); fpos = malloc(sizeof(long)*15000000); if (fpos == NULL) exit(0); fpos[++k] = ftell(fp); while((fgets(s,BUF - 1, fp))) { fpos[++k] = ftell(fp); } int j = 1; fseek(fp,fpos[--k],SEEK_SET); while(fgets(s,BUF - 1,fp)) { if(k > 0) { printf("%4d:%s", j++, s); fseek(fp,fpos[--k],SEEK_SET); } } free(fpos); fclose(fp); } else { printf("ファイル[%s]がありません\n",argv[i]); return -1; } } return 0; }