文件索引

2/22/2017来源:ASP.NET技巧人气:2901

索引的作用(为什么要有索引?):

当要对大数据文件进行随机 读取时,一种方法是先全部读入内存,以数组形式存储,通过数组索引下标形式进行访问,

缺点是要占用大量的内存,我们知道对计算机而言内存是相当宝贵的。

另一种方法就是建立文件索引,通过文件索引查找数据。思路:把每一行字符串的数据首地址记录下来,存入数组,再通过文件指针访问数组中的存储地址所指向的数据。 

程序步骤

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