目录
引言
一、文件与目录操作
1. 打开与关闭文件
2. 文件读写操作
3. 文件定位与错误处理
二、字符流与字节流
1. 字符流处理
2. 字节流处理
三、序列化与反序列化
1. 序列化
2. 反序列化
四、新的I/O(NIO)
表格总结
文件与目录操作
字符流与字节流
序列化与反序列化
总结
引言
输入输出(I/O)操作是C语言程序与外部环境交互的重要手段。通过I/O操作,程序可以读取用户输入、访问文件系统以及输出结果到屏幕或文件。本篇文章将详细介绍C语言中的I/O操作,包括文件与目录操作、字符流与字节流、序列化与反序列化及新的I/O(NIO)等内容,帮助读者全面理解和掌握C语言中的I/O操作。
一、文件与目录操作
文件与目录操作是C语言中最常见的I/O操作之一。C语言提供了一组标准库函数,便于程序员对文件和目录进行创建、读写和删除等操作。
1. 打开与关闭文件
在C语言中,使用fopen
函数打开文件,使用fclose
函数关闭文件。文件可以以不同的模式打开,如读、写、追加等。
示例代码:
#include <stdio.h>int main() {FILE *file;// 以读模式打开文件file = fopen("example.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}// 关闭文件fclose(file);return 0;
}
2. 文件读写操作
C语言中提供了多种文件读写函数,如fscanf
、fprintf
、fgets
、fputs
等。
示例代码:
#include <stdio.h>int main() {FILE *file;char buffer[100];// 写入文件file = fopen("example.txt", "w");if (file == NULL) {printf("无法打开文件\n");return 1;}fprintf(file, "Hello, world!\n");fclose(file);// 读取文件file = fopen("example.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}fgets(buffer, 100, file);printf("读取到的内容: %s", buffer);fclose(file);return 0;
}
3. 文件定位与错误处理
C语言提供了文件指针定位函数(如fseek
、ftell
、rewind
)及错误处理函数(如ferror
和clearerr
)。
示例代码:
#include <stdio.h>int main() {FILE *file;long pos;// 以读模式打开文件file = fopen("example.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}// 移动文件指针到文件末尾fseek(file, 0, SEEK_END);// 获取文件指针位置pos = ftell(file);printf("文件大小: %ld 字节\n", pos);// 关闭文件fclose(file);return 0;
}
二、字符流与字节流
字符流和字节流是处理数据流的两种基本方式。字符流处理文本数据,而字节流处理二进制数据。
1. 字符流处理
字符流适用于处理文本文件,通过函数如fgetc
、fputc
、fgets
、fputs
等进行操作。
示例代码:
#include <stdio.h>int main() {FILE *file;char ch;// 以读模式打开文件file = fopen("example.txt", "r");if (file == NULL) {printf("无法打开文件\n");return 1;}// 逐字符读取文件while ((ch = fgetc(file)) != EOF) {putchar(ch);}// 关闭文件fclose(file);return 0;
}
2. 字节流处理
字节流适用于处理二进制文件,通过函数如fread
和fwrite
操作。
示例代码:
#include <stdio.h>int main() {FILE *file;int buffer[5] = {1, 2, 3, 4, 5};// 写入二进制文件file = fopen("data.bin", "wb");if (file == NULL) {printf("无法打开文件\n");return 1;}fwrite(buffer, sizeof(int), 5, file);fclose(file);// 读取二进制文件file = fopen("data.bin", "rb");if (file == NULL) {printf("无法打开文件\n");return 1;}fread(buffer, sizeof(int), 5, file);for (int i = 0; i < 5; i++) {printf("buffer[%d] = %d\n", i, buffer[i]);}fclose(file);return 0;
}
三、序列化与反序列化
序列化是将对象转换为字节流的过程,以便存储或传输数据;反序列化是将字节流转换为对象的过程。C语言通过自定义函数实现序列化和反序列化。
1. 序列化
序列化的目的是将数据结构转换为二进制格式,以便存储到文件或通过网络传输。
示例代码:
#include <stdio.h>typedef struct {int id;char name[50];
} Person;void serialize(Person *person, FILE *file) {fwrite(person, sizeof(Person), 1, file);
}int main() {Person person = {1, "John Doe"};FILE *file = fopen("person.dat", "wb");if (file == NULL) {printf("无法打开文件\n");return 1;}serialize(&person, file);fclose(file);return 0;
}
在上面的示例代码中,我们定义了一个Person
结构体,并通过serialize
函数将其写入到二进制文件person.dat
中。
2. 反序列化
反序列化的目的是将二进制格式的数据转换回原来的数据结构。
示例代码:
#include <stdio.h>typedef struct {int id;char name[50];
} Person;void deserialize(Person *person, FILE *file) {fread(person, sizeof(Person), 1, file);
}int main() {Person person;FILE *file = fopen("person.dat", "rb");if (file == NULL) {printf("无法打开文件\n");return 1;}deserialize(&person, file);fclose(file);printf("ID: %d, Name: %s\n", person.id, person.name);return 0;
}
在上面的示例代码中,我们通过deserialize
函数从二进制文件person.dat
中读取数据,并将其转换回Person
结构体。
四、新的I/O(NIO)
新的I/O(NIO)是一种改进的I/O处理方式,通常通过第三方库实现。NIO提高了数据处理的性能和效率,尤其在大规模数据处理和网络应用中。然而,C语言标准库中不包含NIO实现,但可以借助操作系统提供的系统调用及第三方库(如libuv、Boost.Asio)实现NIO。
表格总结
文件与目录操作
操作 | 函数 | 示例 |
---|---|---|
打开文件 | fopen | file = fopen("example.txt", "r"); |
关闭文件 | fclose | fclose(file); |
读写文本文件 | fscanf 、fprintf 、fgets 、fputs | fscanf(file, "%d", &num); |
文件定位 | fseek 、ftell 、rewind | fseek(file, 0, SEEK_END); |
字符流与字节流
类型 | 操作 | 函数 | 示例 |
---|---|---|---|
字符流 | 读取字符 | fgetc | ch = fgetc(file); |
字符流 | 写入字符 | fputc | fputc(ch, file); |
字符流 | 读取字符串 | fgets | fgets(buffer, 100, file); |
字符流 | 写入字符串 | fputs | fputs(buffer, file); |
字节流 | 读取字节 | fread | fread(buffer, size, count, file); |
字节流 | 写入字节 | fwrite | fwrite(buffer, size, count, file); |
序列化与反序列化
操作 | 函数 | 示例 |
---|---|---|
序列化 | fwrite | fwrite(person, sizeof(Person), 1, file); |
反序列化 | fread | fread(person, sizeof(Person), 1, file); |
总结
输入输出(I/O)操作在C语言编程中占据重要地位,包括文件与目录操作、字符流与字节流处理,以及序列化与反序列化。通过深入理解和掌握这些I/O操作,程序员可以实现与外部环境的高效数据交互,为各种应用场景提供稳定可靠的解决方案。无论是文本文件的读写、二进制数据的处理,还是复杂数据结构的序列化和反序列化,这些I/O操作的掌握都对编写高效、健壮的C程序至关重要。