索引的作用(為什么要有索引?):
當要對大數據文件進行隨機 讀取時,一種方法是先全部讀入內存,以數組形式存儲,通過數組索引下標形式進行訪問,
缺點是要占用大量的內存,我們知道對計算機而言內存是相當寶貴的。
另一種方法就是建立文件索引,通過文件索引查找數據。思路:把每一行字符串的數據首地址記錄下來,存入數組,再通過文件指針訪問數組中的存儲地址所指向的數據。
程序步驟
1.讀取文件中一共有多少行數據
2.得到每行數據在文件中的地址
3.寫入索引文件
4.載入索引文件到內存或者直接從索引文件讀取每行數據所在的地址
5.隨機讀取想要讀取的行數
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>char path[256] = "D://C++//test.txt";char indexpath[256] = "D://C++//index.txt";#define N 8000000 //通過getN()得到行數struct index{ int *pindex; //地址 int length; //長度}allindex;int getN() //得到行數{ int i = 0; FILE *pf = fopen(path, "rb"); if (pf == NULL) { return -1; } else { int i = 0; int alllength = 0; while (!feof(pf)) { char str[50] = { 0 }; fgets(str, 50, pf); i++; } //PRintf("/n all = %d", alllength); fclose(pf); return i; }}void init(char *path) // 生成索引并寫入到文件{ printf("索引數組開始分配 /n"); allindex.length = N; allindex.pindex = calloc(N, sizeof(int)); printf("索引數組完成分配 /n"); printf("開始讀取 /n"); FILE *pf = fopen(path, "rb"); if (pf == NULL) { return -1; } else { int alllength = 0; for (int i = 0; i < N; i++) { char str[50] = { 0 }; fgets(str, 50, pf); allindex.pindex[i] = alllength; int length = strlen(str); alllength += length; } fclose(pf); } printf("/n 結束讀取"); printf("/n 開始寫入"); FILE *pfw = fopen(indexpath, "wb"); //寫入索引 fwrite(allindex.pindex, sizeof(int), allindex.length, pfw); fclose(pfw); printf("/n 結束寫入"); free(allindex.pindex); }void readindex() // 讀取索引文件到內存{ printf("索引數組開始分配 /n"); allindex.length = N; allindex.pindex = calloc(N, sizeof(int)); printf("索引數組完成分配 /n"); printf("/n 開始讀取"); FILE *pfw = fopen(indexpath, "rb"); //寫入索引 fread(allindex.pindex, sizeof(int), allindex.length, pfw); fclose(pfw); printf("/n 結束讀取");}void main() //通過讀索引到內存,再訪問大數據文件讀取數據{ init(path); readindex(); FILE *pf = fopen(path, "rb"); while (1) { printf("請輸入要讀取的行數"); int num = 0; scanf("%d", &num); fseek(pf, allindex.pindex[num], SEEK_SET); char str[128] = { 0 }; fgets(str, 128, pf); printf("%s", str); } printf("%d", getN()); system("pause");}void main1() //生成好索引后,直接從索引文件讀取數據地址,再訪問大數據文件讀取數據{ FILE *pf1 = fopen(indexpath, "rb"); FILE *pf2 = fopen(path, "rb"); while (1) { printf("請輸入要讀取的行數"); int num = 0; scanf("%d", &num); int indexnum = 0; fseek(pf1,num *sizeof(int), SEEK_SET); fread(&indexnum, sizeof(int), 1, pf1);//讀索引 fseek(pf2, indexnum, SEEK_SET); char str[128] = { 0 }; fgets(str, 128, pf2); printf("%s", str); } system("pause");}
新聞熱點
疑難解答