【Linux文件IO】标准IO详情(1)
目录
一、前言
1.1 文件类型
1.2 流(FILE)介绍
1.3 文本流和二进制流的区别
二、相关API介绍
2.1 fopen
2.2 fclose
2.3 perror
2.4 fgetc
2.5 fputc
2.6 fgets
2.7 fputs
2.8 fread
2.9 fwrite
一、前言
标准IO基于系统IO实现,通过缓冲机制减少系统调用次数,提高效率。缓冲类型包括:
- 全缓冲:缓冲区满时执行IO操作。
- 行缓冲:遇到换行符或缓冲区满时执行IO操作(常用于终端)。
- 无缓冲:立即执行IO操作(如
stderr
)。
1.1 文件类型
文件类型 | 格式 |
常规文件 | - |
目录文件 | d |
字符设备文件 | c |
块设备文件 | b |
管道文件 | p |
套接字文件 | s |
符号链接文件 | l |
1.2 流(FILE)介绍
标准IO通过FILE
结构体管理文件流,包含以下信息:
- 文件描述符
- 缓冲区指针
- 当前读写位置
- 错误标志位
1.3 文本流和二进制流的区别
平台 | 文本模式( | 二进制模式( |
Windows | 写入 | 直接读写原始数据 |
Linux | 无转换,统一使用 | 同文本模式 |
二、相关API介绍
2.1 fopen
函数原型
FILE *fopen(const char *path, const char *mode);
函数功能
打开一个文件
参数说明
path:要打开的文件的路径(绝对、相对)。
mode:
模式 | 作用 |
r | 只读,文件必须存在。 |
w | 只写,文件存在则清空,不存在则创建。 |
a | 追加,文件不存在则创建。 |
+(r+ w+ a+) | 已读写的方式打开文件,其他就要看+前面的参数。 |
b(rb wb ab r+b w+b a+b) | 使用二进制的形式进行读或者写或者追加 |
函数返回值
成功时返回流指针,失败返回NULL。
示例
fopen("test.txt", "r+")
注意点
1.打开绝对路径里面的斜杠要两条
FILE *fp = fopen("D:\\tmp\\test.c", "r");
2.2 fclose
函数原型
int fclose(FILE *stream);
函数功能
关闭指定的文件流。
参数说明
stream:要关闭的文件指针。
函数返回值
成功关闭文件时,返回 0。
如果关闭文件失败,返回 EOF
(宏定义,通常为 -1)。
示例
fclose(fp);
2.3 perror
函数原型
void perror(const char *s);
函数功能
输出最近一次错误信息到标准错误流(stderr)。
参数说明
s:指向一个以空字符结尾的字符串(C风格字符串)。如果传入 NULL,则只打印错误信息。
函数返回值
无返回值。
示例
#include <stdio.h>
#include <errno.h>
int main() {
FILE *file = fopen("nonexistent_file.txt", "r");
if (file == NULL) {
// 打印错误信息
perror("Failed to open file");
return 1;
}
// 如果文件打开成功,关闭文件
fclose(file);
return 0;
}
/* 结果 */
如果文件不存在
Failed to open file: No such file or directory
注意点
1.perror会根据全局变量errno来打印错误信息,如果在多线程环境中使用可能会出现错误。建议是用strerror函数结合errno。
2.4 fgetc
函数原型
int fgetc(FILE *fp);
函数功能
从文件中获取一个字符。
参数说明
fp:要操作的文件指针。
函数返回值
成功返回字符的int值,失败或到达文件末尾返回EOF。
示例
FILE* fp = fopen("text.txt", "r");
int ch = fgetc(fp);//这里fgetc的返回值是int类型的。
printf("%c", ch);
2.5 fputc
函数原型
int fputc( int ch, FILE *fp );
函数功能
向文件中写一个字符。
参数说明
ch:要写入的字符,写入的是其低8位。
fp:要写入的文件指针。
函数返回值
成成功返回写入字符,失败返回EOF。
示例
FILE* fp = fopen("text.txt", "w");
fputc('a', fp);
fclose(fp);
2.6 fgets
函数原型
char *fgets(char *s, int size, FILE *stream);
函数功能
从指定的流stream读取一行,并把它存储在str所指向的字符串内。当读取(n-1)个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
参数说明
s:这是指向一个字符数组的指针,该数组存储了要读取的字符串。
size :这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
stream:文件指针。
函数返回值
成功返回s,到达文件末尾或未读取到字符返回NULL。
示例
int main()
{
char line[256];
FILE* fp = fopen("text.txt", "r+");
if (fp == NULL){
printf("open failed!");
return 0;
}
/* 从fp文件指针中读取字节读完这一行(\n)或者255字节(256字节补\0)或者到EOP */
fgets(line, sizeof(line), fp);
printf("%s", line);
return 0;
}
2.7 fputs
函数原型
int fputs(char * str, FILE *stream);
函数功能
写入字符串(需手动换行)。
参数说明
str :要写入的字符串。
stream :要写入的文件指针。
函数返回值
该函数返回一个非负值,如果发生错误则返回 EOF。
示例
int main()
{
char line[256] = "\nnebula";
FILE* fp = fopen("text.txt", "a+");
if (fp == NULL){
printf("open failed!");
return -1;
}
fputs(line, fp);
return 0;
}
2.8 fread
函数原型
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
函数功能
从文件中读取一片内容。
参数说明
ptr:存储读取数据的指针。
size:每个数据项的大小(以字节为单位)。
nmemb:要读取的数据项的个数。
stream:要写入的文件指针。
函数返回值
返回成功读取的数据项的个数。如果返回值小于 count,可能是到达文件末尾或发生错误。
示例
int main()
{
char buff[20] = {0};
FILE* fp = fopen("text.txt", "r+");
if (fp == NULL){
printf("open failed!");
fclose(fp);
return -1;
}
fread(buff, sizeof(buff), 1, fp);
printf("%s", buff);
fclose(fp);
return 0;
}
2.9 fwrite
函数原型
size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
函数功能
把数据写到文件里面。
参数说明
ptr:要写入的数据指针。
size:每个数据项的大小(以字节为单位)。
nmemb:要写入的数据项的个数。
stream:这是指向 FILE 对象的指针,该 FILE 对象指定了一个输出流。
函数返回值
返回成功写入的数据项的个数。如果返回值小于 count,则表示写入过程中发生了错误。
示例
int main()
{
char buff[20] = "i eat apple";
FILE* fp = fopen("text.txt", "w+");
if (fp == NULL){
printf("open failed!");
fclose(fp);
return -1;
}
fwrite(buff, sizeof(buff), 1, fp);
fclose(fp);
return 0;
}