当前位置:嗨网首页>书籍在线阅读

33-用二进制IO进行随机访问

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

13.7.9 用二进制I/O进行随机访问

随机访问是用二进制I/O写入二进制文件最常用的方式,我们来看一个简短的例子。程序清单13.6中的程序创建了一个存储 double 类型数字的文件,然后让用户访问这些内容。

程序清单13.6  randbin.c 程序

/* randbin.c -- 用二进制I/O进行随机访问 */
#include <stdio.h>
#include <stdlib.h>
#define ARSIZE 1000
int main()
{
     double numbers[ARSIZE];
     double value;
     const char * file = "numbers.dat";
     int i;
     long pos;
     FILE *iofile;
     // 创建一组 double类型的值
     for (i = 0; i < ARSIZE; i++)
          numbers[i] = 100.0 * i + 1.0 / (i + 1);
     // 尝试打开文件
     if ((iofile = fopen(file, "wb")) == NULL)
     {
          fprintf(stderr, "Could not open %s for output.\n", file);
          exit(EXIT_FAILURE);
     }
     // 以二进制格式把数组写入文件
     fwrite(numbers, sizeof(double), ARSIZE, iofile);
     fclose(iofile);
     if ((iofile = fopen(file, "rb")) == NULL)
     {
          fprintf(stderr,
               "Could not open %s for random access.\n", file);
          exit(EXIT_FAILURE);
     }
     // 从文件中读取选定的内容
     printf("Enter an index in the range 0-%d.\n", ARSIZE - 1);
     while (scanf("%d", &i) == 1 && i >= 0 && i < ARSIZE)
     {
          pos = (long) i * sizeof(double);    // 计算偏移量
          fseek(iofile, pos, SEEK_SET);       // 定位到此处
          fread(&value, sizeof(double), 1, iofile);
          printf("The value there is %f.\n", value);
          printf("Next index (out of range to quit):\n");
     }
     // 完成
     fclose(iofile);
     puts("Bye!");
     return 0;
}

首先,该程序创建了一个数组,并在该数组中存放了一些值。然后,程序以二进制模式创建了一个名为 numbers.dat 的文件,并使用 fwrite() 把数组中的内容拷贝到文件中。内存中数组的所有 double 类型值的位组合(每个位组合都是64位)都被拷贝至文件中。不能用文本编辑器读取最后的二进制文件,因为无法把文件中的值转换成字符串。然而,存储在文件中的每个值都与存储在内存中的值完全相同,没有损失任何精确度。此外,每个值在文件中也同样占用64位存储空间,所以可以很容易地计算出每个值的位置。

程序的第2部分用于打开待读取的文件,提示用户输入一个值在数组中的索引。程序通过把索引值和 double 类型值占用的字节相乘,即可得出文件中的一个位置。然后,程序调用 fseek() 定位到该位置,用 fread() 读取该位置上的数据值。注意,这里并未使用转换说明。 fread() 从已定位的位置开始,拷贝8字节到内存中地址为 &value 的位置。然后,使用 printf() 显示 value 。下面是该程序的一个运行示例:

Enter an index in the range 0-999.
500
The value there is 50000.001996.
Next index (out of range to quit):
900
The value there is 90000.001110.
Next index (out of range to quit):
0
The value there is 1.000000.
Next index (out of range to quit):
-1
Bye!