1.标准I/O介绍
文件基础
概念:
一组相关数据的有序集合
文件类型:
常规文件 r
目录文件 d
字符设备文件 c 键盘,鼠标
块设备文件 b U盘,SD卡等
管道文件 p
套接字文件 s
符号链接文件 l (类似于快捷方式)
系统调用与库函数:
系统调用:是用户进程进入内核的接口层,它本身并非内核函数,但它是由内核函数实现的,进入内核后,不同的系统调用会找到相应的内核函数,这些内核函数被称为系统调用的“服务例程”。
库函数:函数库是由系统建立的具有一定功能的函数的集合
-
IO的概念
I input 输入设备 比如键盘鼠标都是Input设备
O output 输出设备 比如显示器
优盘,网口,既是输入也是输出 -
系统调用和库函数
系统调用就是操作系统提供的接口函数.
如果我们把系统调用封装成库函数就可以起到隔离的作用,提供程序的可移植性。
Printf就是库函数然后调用了系统调用才在显示器上显示字符。 -
流的概念
就是数据的流,在程序中就是一个结构体。
FILE:标准IO用一个结构体类型来存放打开的的文件的相关信息,标准IO的所有操作都是围绕FILE来进行
流stream:FILE又被称为流, -
Windows 和linux的换行符区别
Windows是\r\n
Linux 是\n -
缓冲区的概念
为了减少操作IO设备的次数,提高运行效率,在内存里面设置的缓冲区,
全缓冲:缓冲区满才输出
行缓冲:遇到换行符输出
无缓冲:数据直接写入文件,流不进行缓
stdin / stdout / stderr
stdin/stdout 默认是行缓冲,stderr没有缓冲
三种标准IO :
标准错误:无缓冲
perror 库函数 头文件stdio.h
strerror 库函数 头文件 errno.h string.h
perror和strerror 功能:打印系统的错误描述(注意:是系统错误,不是你自己代码错误)
代码如下:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc,char * argv[]){
FILE *fp = NULL;
if((fp = fopen("./1.txt", "r")) == NULL){
perror("fopen");
printf("%s",strerror(errno));
}else{
printf("fopen success!\n");
}
return 0;
}
2.缓存区代码验证
#include <stdio.h>
#include <unistd.h>
int main()
{
// printf("hello world");
printf("hello world\n");
while(1){
sleep(1);
}
return 0;
}
#include <stdio.h>
#include <unistd.h>
int main()
{
int i = 0;
for(i = 0;i < 1025;i++){
printf("a");
}
while(1){
sleep(1);
}
return 0;
}
前后两次实验,在没加换行符时不打印,加换行符后打印hello world,说明stdout(标准输出)是行缓冲,而且缓冲区大小是1K
3.文件的打开与关闭
通俗的来说,文件打开就是占用资源,关闭就是释放资源
3.1 文件的打开
- 文件的打开函数
FILE *fopen (const char *path, const char *mode);
Path: 普通文件当前路径不需要加目录,其他要使用完整的路径
Mode:r / r+ / w / w+ / a / a+
返回值:出错返回NULL,所以使用fopen函数必须判断是否为空
mode | 描述 |
---|---|
“r” 或 “rb” | 以只读方式打开文件,文件必须存在。 |
“r+” 或 ”r+b” | 以读写方式打开文件,文件必须存在。 |
“w” 或 “wb” | 以只写方式打开文件,若文件存在则文件长度清为0。若文件不存在则创建。 |
“w+” 或 “w+b” | 以读写方式打开文件,其他同”w”。 |
“a” 或 “ab” | 以只写方式打开文件,若文件不存在则创建;向文件写入的数据被追加到文件末尾。 |
“a+” 或 “a+b” | 以读写方式打开文件。其他同”a” |
#include <stdio.h>
#include <unistd.h>
int main(int argc,char * argv[]){
FILE *fp = NULL;
if((fp = fopen("./1.txt", "r")) == NULL){
perror("fopen");
}else{
printf("fopen success!\n");
}
return 0;
}
3.2 文件的关闭
函数原型:int fclose(FILE *stream)
fclose()调用成功返回0,失败返回EOF(-1),并设置errno
流关闭时自动刷新缓冲中的数据并释放缓冲区,比如:常规文件把缓冲区内容写入磁盘
当一个程序正常终止时,所有打开的流都会被关闭
fclose()函数的入参stream必须保证为非空,否则出现断错误。
linux@linux:~/level4$ ./fopen
fopen: No such file or directory
No such file or directory
linux@linux:~/level4$ touch 1.txt
linux@linux:~/level4$ ./fopen
fopen success!
close success!
linux@linux:~/level4$ cat fopen.c
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
int main(int argc,char * argv[]){
FILE *fp = NULL;
if((fp = fopen("./1.txt", "r")) == NULL){
perror("fopen");
printf("%s\n",strerror(errno));
}else{
printf("fopen success!\n");
if(fclose(fp)==0){
printf("close success!\n");
}
}
return 0;
}