大数据索引
體會代碼,有二種方式。第一種是初始化索引,第二種是在第一種建立好索引的基礎上使用的移動文件指針的方式,減少讀入內存數據的方式移動指針。詳見下面代碼:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<string.h> #include<Windows.h>#define N 84357484//讀取大數據有多少行(不知道行數,無法開辟內存空間) //把索引讀入到 int a[n] 在堆上 //寫入到文件 //索引文件載入到內存 //隨機讀char *path = "E:\\qq.txt"; char *index = "E:\\qqindex.txt";struct index //索引的數據結構 {int *pindex; //每行的首地址int length; //行數 }allindex;int getLine(char *path) {int line = 0;FILE *pfr = fopen(path, "rb");if (pfr == NULL){printf("文件打開失敗!\n");return -1;}else{while (!feof(pfr)){char str[256] = { 0 };fgets(str, 256, pfr);line++;}fclose(pfr);}return line; }//初始化數據 void initindex(char *path) {printf("索引數組開始分配...\n");allindex.length = getLine(path);allindex.pindex = calloc(N, sizeof(int)); //開辟內存空間printf("索引數組完成分配。\n");printf("開始讀取...\n");FILE *pfr = fopen(path, "rb");FILE *pfw = fopen(index, "wb"); //索引文件if (pfr == NULL || pfw == NULL){printf("文件打開失敗!\n");return;}else{int alllength = 0;int i = 0;while (!feof(pfr)){char str[256] = { 0 };fgets(str, 256, pfr);//記錄每行數據所占用的長度,方便后面指針查詢的跳轉allindex.pindex[i] = alllength; int length = strlen(str);alllength += length;i++;}fclose(pfr);}printf("結束讀取...\n");//把索引寫入到文件中printf("索引寫入...\n");fwrite(allindex.pindex, sizeof(int), allindex.length, pfw);fclose(pfw);printf("索引寫入結束。\n");//釋放內存//free(allindex.pindex);/*printf("開始讀取...\n");FILE *pfr1 = fopen("E:\\qqindex.txt", "rb");fread(allindex.pindex, sizeof(int), allindex.length, pfr1);fclose(pfr1);printf("結束讀取...\n");*/ }//快速讀取,就是建立好索引文件后,直接讀取索引文件 void qucik(char *path) {printf("索引數組開始分配...\n");allindex.length = getLine(path);allindex.pindex = calloc(N, sizeof(int)); //開辟內存空間printf("索引數組完成分配。\n");printf("開始讀取...\n");FILE *pfr1 = fopen("E:\\qqindex.txt", "rb");fread(allindex.pindex, sizeof(int), allindex.length, pfr1);fclose(pfr1);printf("結束讀取...\n"); }void main1() {//int line = getLine(path);//printf("%d\n", line);initindex(path); //初始化//qucik(path); //這是在上面的 初始化 后有了索引文件后可以這樣快速執行。FILE *pfr = fopen(path, "rb");while (1){printf("\n請輸入要讀取的行數:");int num = 0;scanf("%d", &num);fseek(pfr, allindex.pindex[num], SEEK_SET);char str[256] = { 0 };fgets(str, 256, pfr);printf("%s\n", str);}fclose(pfr);system("pause"); }// 因為索引文件保存的是int 數組,而數據排列是線性的,即每個數據所占的空間大小都一樣。 //這時可以按指針移動,來跳到索引處(因為每個索行保存的每行數據的首地址),這時讀出 //索引的值,然后再移動數據指針到相應的文件處,讀出其中的 數據,這樣可以使用較小的 //內存,可以完成對大數據的查詢。不過首先要建立好索引。void main() {FILE *pf1 = fopen(path, "rb");//數據文件FILE *pf2 = fopen(index, "rb");//索引文件if (pf1 == NULL || pf2 == NULL){printf("文件打開失敗!\n");return;}while (1){printf("\n請輸入要讀取的行數:");int num = 0;scanf("%d", &num);int index =0;fseek(pf2,num*sizeof(int) , SEEK_SET); //移動指針在索引文件中查詢fread(&index, sizeof(int), 1, pf2); //讀出索引文件的值。fseek(pf1, index, SEEK_SET);char str[256] = { 0 };fgets(str, 256, pf1);printf("%s\n", str);}fclose(pf1);fclose(pf2); }總結
- 上一篇: package.json字段详解
- 下一篇: 任正非首谈接班人制度