今天,刘斌师兄找我问了几个问题,是关于他毕设遇到的一个问题,处理大文件。

刚开始,刘斌问了一个大文件如何处理的问题,我说GCC有一个处理大文件的选项。后来,他又跟我说了一下他毕设的一些详细的资料。原来,他是要索引一个大文件,苦于文件比较大。

索引大文件,会遇到一些问题。首先就是内存的问题,当然不能够完全使用物理内存,需要使用交换分区。我们做了几个实验,来验证一下,程序分配大空间跟交换分区的关系。

1、在一个没有交换分区的机器上实验。

char *p = NULL;

for(int i = 0 ; i < 10; i ++){

p = malloc(100000000);

bzero(p,   100000000);

printf("###%#0x\n",p);

}

程序是分配10*100M的空间,远远大于系统的内存,结果程序出现段错误。如果是还一个小一点的数的话,就没有问题了(废话,就不就是要处理大文件吗)。

如果注释掉bzero一行的话,运行的时候,就会发现内存并没有占用多少。可以判定如果申请内存的时候没有赋值的话,实际上系统并没有分配。

2、在一个有交换分区的机器上实验。

char *p = NULL;

for(int i = 0 ; i < 10; i ++){

p = malloc(100000000);

bzero(p,   100000000);

printf("###%#0x\n",p);

}

物理内存:512M

交换分区:720M

分配没有问题,就是系统有一些慢。用free查看内存占用的话,就会发现,物理内存只剩下6M了,交换分区占用了500M。

ft,再实验,将数再改的大一些!

char *p = NULL;

for(int i = 0 ; i < 10; i ++){

p = malloc(150000000);

bzero(p,   150000000);

printf("###%#0x\n",p);

}

10*150M > 512M + 720M,这下看一下会不会出现段错误。

编译运行,哈哈,出现段错误了,看来预测是对的了。

3、增加交换分区,再实验

接下来就是要增加交换分区,再实验一下,其实结果应该很清楚了,不过还是想看一下。

增加交换分区有两个方法:增加一块硬盘作为交换分区,使用一个文件作为交换分区。

我的硬盘已经没有空的了,只好使用文件作为交换分区了。

dd if=/dev/zero of=./swapfile bs=1M count=500

mkswap ./swapfile

swapon ./swapfile

在运行刚才的程序,分配成功,Yes!

4、大内存访问实验。

虽然解决了大内存分配的问题,但是索引大文件还是需要对大内存进行随机访问,这就是一个问题了.

由于32位的机器实际上只能够访问4G的地址空间,如果文件有5G,那么怎么来访问4G之外的存储器呢?

正如上面,malloc一样,malloc的参数是一个size_t的数,最大才4G。我们只好拆开来分配。

访问也是一样,我们也可以拆开来访问吗?

5G=4G+1G

void *temp = p + 4G;

temp += 5G-4G

就可以访问到5G的区域了。