大数据索引

来源:互联网 发布:炮火兰捏脸数据 编辑:程序博客网 时间:2024/06/04 20:10

体会代码,有二种方式。第一种是初始化索引,第二种是在第一种建立好索引的基础上使用的移动文件指针的方式,减少读入内存数据的方式移动指针。详见下面代码:

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


0 0