14 文件操作之文件定位与缓冲
在 C 语言的文件操作中,文件定位和缓冲是两个非常重要的概念。它们直接影响着文件的读写效率和程序的执行效率。本节将深入探讨如何在文件中进行定位,以及缓冲机制的工作原理。
文件定位
文件定位涉及到如何在打开的文件中移动文件指针。C 语言为文件定位提供了一些标准函数,最常用的函数是 fseek()、ftell() 和 rewind()。
1. fseek()
fseek() 函数用于移动文件指针到指定的位置。其函数原型如下:
int fseek(FILE *stream, long offset, int whence);
stream:文件指针。offset:要移动的字节数。whence:基准位置,可以是:SEEK_SET:从文件头开始。SEEK_CUR:从当前位置开始。SEEK_END:从文件末尾开始。
示例:
#include <stdio.h>
int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Unable to open file");
        return 1;
    }
    // 移动到文件开始位置
    fseek(file, 10, SEEK_SET);
    // 获取当前位置
    long pos = ftell(file);
    printf("Current position: %ld\n", pos);
    // 移动到文件末尾
    fseek(file, 0, SEEK_END);
    pos = ftell(file);
    printf("End position: %ld\n", pos);
    fclose(file);
    return 0;
}
在上面的例子中,我们打开一个文件并移动文件指针到第 10 个字节的位置,然后打印当前指针位置,接着我们将指针移动到文件末尾并输出其位置。
2. ftell()
ftell() 函数用于获取当前文件指针的位置,其原型如下:
long ftell(FILE *stream);
它返回当前文件指针的字节偏移量。如果出错,返回 -1。
3. rewind()
rewind() 函数用于将文件指针移动到文件开头,其原型如下:
void rewind(FILE *stream);
与 fseek() 不同,rewind() 不需要偏移参数。
示例:
#include <stdio.h>
int main() {
    FILE *file = fopen("example.txt", "r");
    if (file == NULL) {
        perror("Unable to open file");
        return 1;
    }
    // 读取文件的前10个字节
    char buffer[11];
    fread(buffer, 1, 10, file);
    buffer[10] = '\0'; // 添加字符串结束符
    printf("Read first 10 bytes: %s\n", buffer);
    // 重置文件指针
    rewind(file);
    // 读取文件的前10个字节
    fread(buffer, 1, 10, file);
    printf("Read first 10 bytes again: %s\n", buffer);
    fclose(file);
    return 0;
}
总结文件定位
- 使用 
fseek()可以灵活控制文件指针的位置。 ftell()用于获取当前指针位置,而rewind()用于返回文件开头。- 文件定位在处理大文件、随机访问数据时非常有用。
 
文件缓冲
文件缓冲是一种提高 I/O 性能的机制。C 语言的 stdio.h 提供了缓冲文件的功能,允许 C 语言在内存中临时存储数据,从而减少对磁盘的访问次数。
缓冲类型
C 语言中的文件指针可以是三种缓冲模式之一:
- 全缓冲(Fully Buffered):在进行大块数据 I/O 时,数据会先被存储到一个大缓冲区中,直至缓冲区满后再写入到磁盘。
 - 行缓冲(Line Buffered):输出缓冲会在每次遇到换行符时或者缓冲区满时写入数据。
 - 无缓冲(Unbuffered):每次 I/O 操作都直接访问磁盘,不使用缓冲区。
 
函数 setvbuf()
setvbuf() 函数用来设置文件流的缓冲模式,其原型如下:
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
buf:自定义缓冲区,如果为NULL,则使用系统默认缓冲区。mode:指定缓冲模式,可以是_IOFBF(全缓冲)、_IOLBF(行缓冲)和_IONBF(无缓冲)。size:缓冲区的大小。
示例:
#include <stdio.h>
int main() {
    FILE *file = fopen("data.txt", "w");
    if (file == NULL) {
        perror("Unable to open file");
        return 1;
    }
    // 设置全缓冲
    char buffer[1024];
    setvbuf(file, buffer, _IOFBF, sizeof(buffer));
    // 写入数据
    fprintf(file, "Hello, World!\n");
    fprintf(file, "This is a test...\n");
    fclose(file);
    return 0;
}
结论
文件定位和缓冲是 C 语言文件操作中不可或缺的部分。合理地利用 fseek()、ftell()、rewind() 可以让我们高效地处理文件。而理解缓冲机制能够极大地提升 I/O 性能,尤其是在处理大量数据时。接下来的内容将会探讨如何处理文本与二进制文件,为你在文件操作的进一步探索打下基础。
