大数据索引

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

#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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值