【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”就会刷新缓冲区
全缓冲:写满缓冲区时才能被刷新
无缓冲:例如标准输入

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值