引入
我们之前讲的,都是对文件的顺序读写,很容易操作,但有时候效率不高。比如,文件中有1000个数据,我们如果需要找到第999号数据,那么需要从1遍历到998才可以。如果是一个城市几百万人的数据呢?所以随机访问应运而生,随机访问不是按数据在文件中的物理位置进行读写
,而是可以对任何位置上的数据进行访问
,显然这种方法比顺序访问高效
的多。
文件位置标记
我们前面说过,w 方式打开是新建(有重名就删除再新建),文件标记在开头。a 方式打开是追加,文件标记在末尾。为了对读写进行控制
,系统位每个文件设置了一个文件读写位置标记
,简称(文件读写标记或文件标记),用来指示接下来要读写的下一个字符的位置
。
- 顺序读文件:一般情况下,在对字符文件进行顺序读写的时候,文件位置标记指向文件开头,这时,如果
对文件进行读的操作
,然后文件位置标记向后移动一个位置
,如果再一次执行读操作,就会将位置2的字符读入,以此类推(我们前面的例子也说过)直到文件尾。 顺序写文件:一般情况下,在对字符文件进行顺序写的时候,文件位置标记指向文件开头,这时,如果对文件进行
写的操作,每写完一个文件位置标记顺序后移一个位置
。然后在下一次执行写操作的时候,把数据写入指针所在位置。直到把全部数据写完,此时文件位置标记在最后一个数据之后(因为写完就向后移动了嘛)。随机读写:如果我们
人为的移动文件标记位置
,文件标记位置可以向前、向后、向文件头、向文件尾移动,然后对该位置进行读写
,这就不是顺序读写了,而是随机读写
。
对
流文件
,我们可以进行顺序读写也可以进行随机读写,关键在于文件读写标记位置的控制方式
。如果是按字节顺序移动
的,就是顺序读写
,如果能将文件位置标记按需要移动到任意位置
的,那就是随机读写
了!
文件位置标记的定位
我们清楚了文件位置标记,也知道了怎样操作文件位置标记是随机读写,怎样操作是顺序读写。现在我们就来看看,如果操作文件标记。
rewind 函数
作用:将文件位置标记重新返回文件的开头,无返回值。
例子
将磁盘中的文件,先输出一次,再复制一份。
1 |
|
无论是输出也好,复制也好,我们之前都讲过,非常简单。但是这两个操作如果连着来,就不简单了,因为要涉及到文件标记位置的问题。第一遍,输出文件的时候,已经到了文件尾,所以我用同样的方式输出第二遍的时候,是没有内容的。第三遍的时候,我是用rewind(fp)
将 fp 的文件位置返回到文件头,此时再看,又能输出了,然后再回到文件头,进行复制文件。
fseek 函数
作用:用于改变文件位置标记。
一般形式是
fseek(文件类型指针,位移量,起始点)
- 文件类型指针:我们就不说了
- 起始点:用0、1、2表示,0 代表
文件开始位置
,1 代表当前位置
,2 代表文件末尾位置
。
起始点 | 名字 | 数字代表 |
---|---|---|
文件开始位置 | SEEK_SET | 0 |
文件当前位置 | SEEK_CUR | 1 |
文件末尾位置 | SEEK_END | 2 |
- 位移量:以
起始点为基点,向前移动的字节数
,位移量应该是 long 型数据。
在数字末尾加一个字母 L 就表示 long 型
1 | fseek(fp,100L,0); |
注意
一定要记住加 L 表示 long 型数据
ftell 函数
作用:获取
流式文件中文件位置标记的当前位置
。
因为位置总是变来变去的嘛,所以我们经常记不住当前位置,ftell 函数就可以帮我们把当前位置保存下来。如果调用函数出错,则返回-1L
。
1 | i=ftell(fp); |
尾巴
这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。