一、标准 I/O 和系统 I/O的区别
1.高层接口 vs 低层接口
1、标准 I/O:
(1)标准 I/O 函数是高层接口,提供了一组方便的函数(如 fopen、fprintf、fread 等)来进行文件的读写操作。
(2)它们抽象了底层系统调用,更容易使用,且具有跨平台性。
2、系统 I/O:
(1)系统 I/O 是低层接口,它使用系统调用(如 open、read、write 等)来直接操作文件。
(2)调用提供更底层的控制,但通常需要更多的代码和对操作系统的了解。
2.缓冲
1、标准 I/O:
(1)标准 I/O 函数自动进行缓冲,数据通常首先被读入或写出到一个内部缓冲区,然后根据需要进行实际的 I/O 操作。
(2)可以提高性能,尤其是在频繁的小数据量读写时。
2、系统 I/O:
(1)系统 I/O 通常不提供自动缓冲,你需要自己手动管理缓冲区。
(2)这使得对文件的读写更加直接,但可能需要更多的编程工作。
3.错误处理
1、标准 I/O:
(1)标准 I/O 函数使用 NULL 指针返回错误,可以使用 feof 和 ferror 函数来检查文件尾和错误状态。
(2)错误消息可以通过 perror 函数输出。
2、系统 I/O:
(1)系统 I/O 函数通常返回 -1 来表示错误,可以通过查看 errno 全局变量来获取特定的错误代码,然后使用 perror 或 strerror 函数将错误消息打印出来。
二、"标准I/O"的使用
(1)使用 fopen 函数打开一个文件以供写入,如果文件不存在则创建。如果打开失败,它会使用 perror 函数打印错误消息,并返回错误码 1。
(2)使用 fprintf 函数将文本写入文件。
(3)使用 fclose 函数关闭文件。
(4)使用 fopen 函数再次打开文件以供读取。如果打开失败,它会再次使用 perror 函数打印错误消息,并返回错误码 1。
(5)使用 fgets 函数逐行读取文件内容,直到文件末尾。每一行都会被存储在 buffer 缓冲区中。
(6)使用 printf 函数打印从文件中读取的每一行内容。
(7)使用 fclose 函数关闭文件。
(8)最后,程序返回 0 表示成功结束。
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
int main() {
// 打开一个文件以供写入,如果文件不存在则创建 ("w" 模式)
FILE *file = fopen("stdio_example.txt", "w");
if (file == NULL) {
perror("无法打开文件"); // 打印错误消息并返回错误码
return 1;
}
// 写入文件
fprintf(file, "这是标准I/O写入的文本\n");
fclose(file); // 关闭文件
// 重新打开文件以供读取 ("r" 模式)
file = fopen("stdio_example.txt", "r");
if (file == NULL) {
perror("无法打开文件"); // 打印错误消息并返回错误码
return 1;
}
char buffer[100];
// 逐行读取文件内容,直到文件末尾
while (fgets(buffer, sizeof(buffer), file) != NULL) {
printf("标准I/O读取: %s", buffer); // 打印每行内容
}
fclose(file); // 关闭文件
return 0; // 成功结束程序
}
输出结果:标准I/O读取: 这是标准I/O写入的文本
三、"系统I/O"的使用
(1)使用 open 系统调用打开一个文件以供写入,如果文件不存在则创建,权限为 0644。如果打开失败,它会使用 strerror 函数打印错误消息和错误号,然后返回错误码 1 表示程序异常结束。
(2)使用 write 系统调用将文本写入文件。如果写入失败,它会使用 strerror 函数打印错误消息和错误号,关闭文件,然后返回错误码 1。
(3)使用 close 系统调用关闭文件。
(4)重新使用 open 系统调用打开文件以供读取(“O_RDONLY” 模式)。如果打开失败,它会使用 strerror 函数打印错误消息和错误号,然后返回错误码 1。
(5)使用 read 系统调用逐块读取文件内容,直到文件末尾。每块内容都被存储在 buffer 缓冲区中。
(6)使用 write 系统调用将读取的内容写入标准输出。如果写入失败,它会使用 strerror 函数打印错误消息和错误号,关闭文件,然后返回错误码 1。
(7)使用 close 系统调用关闭文件。
(8)最后,如果一切正常,程序返回 0 表示成功结束。
代码如下(示例):
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
int main() {
// 打开一个文件以供写入,如果文件不存在则创建,权限为 0644
int fd = open("syscalls_example.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
fprintf(stderr, "无法打开文件: %s\n", strerror(errno)); // 打印错误消息和错误号
return 1; // 返回错误码 1 表示程序异常结束
}
// 写入文件
char *text = "这是系统I/O写入的文本\n";
ssize_t bytesWritten = write(fd, text, strlen(text)); // 写入文件内容
if (bytesWritten == -1) {
fprintf(stderr, "写入文件时发生错误: %s\n", strerror(errno)); // 打印错误消息和错误号
close(fd); // 关闭文件
return 1; // 返回错误码 1 表示程序异常结束
}
close(fd); // 关闭文件
// 重新打开文件以供读取 ("O_RDONLY" 模式)
fd = open("syscalls_example.txt", O_RDONLY);
if (fd == -1) {
fprintf(stderr, "无法打开文件: %s\n", strerror(errno)); // 打印错误消息和错误号
return 1; // 返回错误码 1 表示程序异常结束
}
char buffer[100];
ssize_t bytesRead;
// 逐块读取文件内容,直到文件末尾
while ((bytesRead = read(fd, buffer, sizeof(buffer))) > 0) {
ssize_t bytesWritten = write(STDOUT_FILENO, buffer, bytesRead); // 将读取的内容写入标准输出
if (bytesWritten == -1) {
fprintf(stderr, "写入标准输出时发生错误: %s\n", strerror(errno)); // 打印错误消息和错误号
close(fd); // 关闭文件
return 1; // 返回错误码 1 表示程序异常结束
}
}
close(fd); // 关闭文件
return 0; // 成功结束程序
}
输出结果:这是系统I/O写入的文本