【Linux】基础IO 知识点
C文件
1. 写入文件
...
6 FILE *fp=fopen("myfile","w");
...
11 const char*msg="hello world!\n";
12 int count=5;
13 while(count--)
14 {
15 fwrite(msg,strlen(msg),1,fp);
16 }
17 fclose(fp);
其中 fwrite(msg,strlen(msg),1,fp);
用来写入文件,msg 是写入字符串的首地址,strlen(msg) 是写入的标准长度,1是写入的基本单位,fp是写入文件的文件名。
2. 读取文件
1 #include <stdio.h>
2 #include <string.h>
3 #include <error.h>
4 int main()
5 {
6 FILE *fp=fopen("myfile","r");
7 if(!fp)
8 {
9 perror("fopen");
10 }
11 char buf[1024];
12 const char *msg="hello world!\n";
13 while(1)
14 {
15 ssize_t s=fread(buf,1,strlen(msg),fp);
16 if(s>0)
17 {
18 buf[s]=0;
19 printf("%s",buf);
20 }
21 if(feof(fp))
22 {
23 break;
24 }
25 }
26 fclose(fp);
27 return 0;
28 }
其中fread(buf,1,strlen(msg),fp);
函数用来读取fp 中的文件
但是这个函数的返回值和参数要特别注意,小心有坑。
3. 输出信息到显示器上
将C文件信息输出到显示器上有三种方法:
1)fwrite 将信息直接写在标准输出(显示器)上
2)printf 输出
3)fprintf 给文件指定输出位置
以下代码可以验证:
1 #include <stdio.h>
2 #include <string.h>
3
4 int main()
5 {
6 const char* msg="hello fwrite!\n";
7 fwrite(msg,strlen(msg),1,stdout);
8
9 printf("hello printf!\n");
10 fprintf(stdout,"hello fprintf!\n");
11 return 0;
12 }
4. 文件打开方式
r : 只读方式,光标出现在文件开始的位置。
r+/w+ : 读写方式 ,光标在文件开始的位置。
w : 只写方式,光标在文件开始的位置。
a : 追加方式,光标在文件的末尾。
a+ : 读并追加,光标在文件末尾的位置。
C文件主要调用<stdio.h>
头文件中包含的库函数,这些函数本质是对系统调用的封装。操作C文件的函数还有 fseek,ftell,fewind
等。大家在学习C语言时应该接触过,这里就不细讲了。
系统文件 I/O
对于文件,我们也常使用系统接口进行访问
open
其中pathname 是(打开或创建的)文件名,flags 是文件的打开方式,mode 是文件的打开权限。
flags(文件打开方式 )的参数
O_RDONLY :只读
O_WRONLY:只写
O_RDWR:读写
上述三个常量必须指定一个且只能指定一个
O_CREAT:若文件不存在就创建,需要mode指明文件的权限
O_APPEND:追加写
返回值
成功:新打开文件的文件描述符
失败:-1
read
read(0,buf,sizeof(buf));
其中第一个参数是从哪里开始读,第二个参数是读的内容,第三个参数是读的大小。
函数返回值: 成功: >0 失败:<0 读到结尾:=0
write
write(1,buf,strlen(bf));
FILE 及 缓冲区
FILE 结构体是由C库定义的,且必定是在系统调用基础上封装了fd。
首先看下面代码的现象:
#include <stdio.h>
#include <string.h>
int main()
{
const char* s1="hello printf\n";
const char* s2="hello fwrite\n";
const char* s3="hello write \n";
printf("%s",s1);
fwrite(s2,strlen(s2),1,stdout);
write(1,s3,strlen(s3));
fork();
return 0;
}
通过结果,我们发现即使同样被fork()了一个子进程,但是fwrite在显示器上打印一次却在file中打印两次,而write 无论在哪里都只被打印一次。这是为什么呢?
这里其实是因为缓冲区刷新条件的缘故。
一般库函数在写入文件时是全缓冲而写入显示器是行缓冲;系统函数无论在哪都是行缓冲。
所以在显示器上,二者都只能输出一次。
但在文件中:这时因为库函数调用fwrite()时默认全缓冲,因此函数在调用fork()时子进程仍可以拷贝父进程缓冲区中的内容,最后进程退出时统一刷新文件缓冲区,所以文件中出现了两份相同的内容。而系统调用write()时仍默认行缓冲,函数在调用fork()时,父进程缓冲区内内容已被刷新出去,子进程发现没有内容可以拷贝,就只有一份内容。
此时若我们强制刷新库函数的缓冲区会发生什么现象呢?
下面是我用fflush(stdout);
刷新printf 缓冲区后的现象
经此验证,我们发现库函数会自带缓冲区,但是系统调用没有带缓冲区。我们又知道库函数调用在系统调用的上层,所以说明缓冲区是通过C库二次加上去的。
这里需要注意:
行缓冲:遇到“\n”就会刷新缓冲区
全缓冲:写满缓冲区时才能被刷新
无缓冲:例如标准输入
还没有评论,来说两句吧...