一、文件
总结一句话:LINUX系统中,一切皆文件。
二、文件类型b
查看文件详细信息命令 :ls -l
-
常规文件:标识符号 “-”
普通文件.c .txt .sh .h .cpp …
二进制文件 a.out -
目录文件: 表示符号 “d”
-
字符设备文件: 表示符号 “c”
-
块设备文件: 表示符号 “b”
-
管道文件: 表示符号 “p”
-
套接字文件: 表示符号“s”
-
符号链接文件: 表示符号 “l”
三、文件I/O和标准I/O
文件I/O
系统调用:当我们的应用程序要使用一些底层的功能的时候,不应该自行访问底层,而应该向操作系统发出请求。
特点:
1. 不带缓存区。
2. 操作系统直接提供的函数接口。
3. 系统调用是很耗费资源的。
标准I/O
C库函数:在系统调用接口之上封装的接口,一个C库函数可以封装多个系统调用函数。
作用:
1. 增强了代码的可移植性,复用性。
2. 提高了效率。
标准IO增加了一个【缓存机制】。
四、标准I/O
1.fopen
头文件:#include <stdio.h>
函数:FILE *fopen(const char *path, const char *mode);
功能:打开文件
参数:
path: 文件的路径 例如:"./1.txt"
mode: 打开方式
r : 以只读的方式打开文件,文件必须存在
r+ : 以读写的方式打开文件,文件必须存在
w : 以写的方式打开文件,文件不存在,则创建
文件存在,则清空
w+ : 以读写的方式打开文件,文件不存在,则创建
文件存在,则清空
a : 以追加的方式打开文件(写),文件不存在,则创建
文件存在,则再文件的末尾追加
a+ : 以追加的方式打开文件(读写),文件不存在,则创建
文件存在,则再文件的末尾追加
返回值:
成功: FILE * (流指针 === 结构体指针)
失败: NULL
实例:FILE *fp = fopen("./1.txt", "w+");
2.fclose
函数:int fclose(FILE *fp);
功能:关闭文件
参数:文件流指针
fp:流指针
为什么要关闭一个文件?
1)防止其他进程操作这个文件
2)释放结构体占用的资源
在程序结束时,系统自动回收资源(不完全),所以尽量写上fclose。
实例:fclose(fp);------fp为对应打开的文件流指针。
3. 缓存区
1.行缓存
printf、stdin 、stdout是行缓存,缓存区大小是 1024byte == 1Kbyte。
刷新行缓存的方式:
1.行缓存满了或遇到'\n'输出条件。
2.fflush可以强制刷新。fflush(fp)
3.文件关闭的时候。fclose(stdout)
4.程序结束的时候。如遇到exit return
下面实例说明:
int main(int argc, const char *argv[])
{
printf("hello world\n"); //1. 遇到'\n'会刷新缓存区,可以打印出来
printf("hello world"); //2.没有刷新,无法打印出来
//行缓存的大小
printf("size=%d\n", stdout->_IO_buf_end - stdout->_IO_buf_base);
fflush(stdout); //3.强制刷新标准输出流
fclose(stdout); //4.关闭流指针
while(1);
return 0; //5.程序结束时 exit(0)
}
2.无缓存
stderr
3.全缓存
通过fopen函数打开的流指针,这个流指针fp的缓冲区大小是 4*1024 4Kbyte
1.缓存区满
2.fclose(fp)
3.return
4.exit
5.fflush(fp)
4.fgetc
函数:int fgetc(FILE *stream);
功能:读取一个字节的数据
参数:stream: 流指针
返回值:
成功:返回这个字节
失败:-1
int c = fgetc(fp);
5.fputc
函数:int fputc(int c, FILE *stream);
功能:写入一个字节的数据
参数:c: 字节、stream: 流指针
返回值:
成功:0
失败:-1
fputc( 'a' , fp); //向fp流指针的文件写入单个字节的数据
6.fgets
函数:char *fgets(char *s, int size, FILE *stream);
功能:读取一行的数据
参数:
s: 内存地址 char s[N];
size: 内存空间的大小 N
stream: 流指针
返回值:
成功:返回读取字符串的首地址
失败:NULL
char buf[1000] = {0};
fgets(buf, sizeof(buf), fp); //将fp流指针指向的文件里一行数据读出来,写入buf数组中
7.fputs
函数:int fputs(const char *s, FILE *stream);
功能:写入一行的数据
参数:
s: 内存地址 char s[N];
stream: 流指针
返回值:
成功:1
失败:-1
int main(int argc, const char *argv[])
{
FILE *fp = fopen("./aa.txt", "w");//打开文件,w为写,没有文件创建文件
if(fp == NULL)
{
perror("fopen");
return -1;
}
char buf[100] = "hello world\n";
int n = fputs(buf, fp);//将buf内容写入fp指向的文件aa.txt
printf("n=%d\n", n);//打印返回值
printf("write success!\n");
fclose(fp);
return 0;
}
8.fseek
函数:int fseek(FILE *stream, long offset, int whence);
功能:定位文件指针
参数:
stream: 流指针
offset: 偏移量
100:向后偏移100个字节
-100:向前偏移100个字节
whence: 基点
SEEK_SET: 文件开头
SEEK_END: 文件末尾
SEEK_CUR: 文件当前位置
返回值:
成功:0
失败:-1
9.ftell
函数:long ftell(FILE *stream);
返回值:当前文件指针的位置
10.rewind
函数:void rewind(FILE *stream);
功能:文件指针返回到文件开头
int main(int argc, const char *argv[])
{
FILE *fp = fopen("./1.txt", "r");
if(fp == NULL)
{
perror("fopen");
return -1;
}
//把文件指针移到末尾
fseek(fp, 0, SEEK_END);
int n = ftell(fp);
printf("n=%d\n", n);
//把文件指针移到开头
fseek(fp, 0, SEEK_SET);
int m = ftell(fp);
printf("m=%d\n", m);
//把文件指针移到开头
rewind(fp);
int p = ftell(fp);
printf("p=%d\n", p);
fclose(fp);
return 0;
}
未完待续。。。。。。。。。