文件相关系统调用接口open/write/read/close
程序员文章站
2022-07-14 17:35:16
...
1.写(write)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_WRONLY|O_CREAT,0644);//以只写方式打开或不存在的话创建
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
const char* msg = "hello world!\n";
int count = 5;
while(count--)//往文件里写5条程序
{
write(fd,msg,strlen(msg));
}
close(fd);//关闭文件
return 0;
}
编译通过会产生一个file,运行,打开file会看到5个hello world!
有几个文件描述符默认是被占用的(默认被打开),接下来将write()函数里的第一个参数改为“1”,默认往显示器上写。
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_WRONLY|O_CREAT,0644);//以只写方式打开或不存在的话创建
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
const char* msg = "hello world!\n";
int count = 5;
while(count--)//往显示器上写5条程序
{
write(1,msg,strlen(msg));
}
close(fd);//关闭文件
return 0;
}
所以程序一旦运行起来,就是往显示器上写。
所以以后再往显示器上写的时候除了printf,又多了一个系统调用接口,write。本质*问文件是要通过系统调用接口中的文件描述符来访问。
2.读(read)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只读方式打开
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
const char* msg = "hello world\n";
int size = sizeof(msg);
char buf[64];
int count = 5;
while(count--)//从文件里读
{
read(fd,buf,size);//从fd里读,将读到的内容写到buf里
printf("%s",buf);
}
close(fd);//关闭文件
return 0;
}
以上代码的运行结果会出现一些问题
因为我们在写文件的时候没有把‘\0’写入,但在读的时候不一定会加上
修改代码:
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只读方式打开
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
const char* msg = "hello world\n";
int size = strlen(msg);
char buf[64];
while(1)//从文件里读
{
size_t s = read(fd,buf,size);//从fd里读,将读到的内容写到buf里
if(s > 0)//如果s大于零说明读成功了,如果读成功了代表的含义是实际读了多少
{
buf[s] = 0;//把最后一个元素设置为零
}
else if(s == 0)//如果返回值为0则读到文加结尾
{
break;
}
printf("%s",buf);
}
close(fd);//关闭文件
return 0;
}
如果把read()函数的第一个参数改为‘0’,代表标准输入,一旦程序运行起来就会停在那里等用户输入。
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只读方式打开
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
const char* msg = "hello world\n";
int size = strlen(msg);
char buf[64];
while(1)//从文件里读
{
size_t s = read(0,buf,size);//将读到的内容写到buf里
if(s > 0)//如果s大于零说明读成功了,如果读成功了代表的含义是实际读了多少
{
buf[s] = 0;//把最后一个元素设置为零
}
else if(s == 0)//如果返回值为0则读到文加结尾
{
break;
}
printf("%s",buf);
}
close(fd);//关闭文件
return 0;
}
最后以ctrl+d结尾。ctrl+d相当于读到文件结尾,读到文件结尾就直接break。
3.现在接口认识完了,那么现在我们来了解一下文件描述符的分配
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只读方式打开
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
printf("fd : %d\n",fd);
return 0;
}
运行结果:
也可以多试几个:
首先touch 3个文件:file1 file2 file3
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd = open("file",O_RDONLY,0644);//以只读方式打开
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
int fd1 = open("file1",O_RDONLY,0644);
int fd2 = open("file2",O_RDONLY,0644);
int fd3 = open("file3",O_RDONLY,0644);
printf("fd : %d\n",fd);
printf("fd : %d\n",fd1);
printf("fd : %d\n",fd2);
printf("fd : %d\n",fd3);
return 0;
}
说明文件描述符的分配确实是从0开始的小整数
如果还是不能确定那再来一段测试代码:
把‘0’和‘2’关掉(不能关‘1’,若关了就不能显示出来,但有可以管的方法,后续会提到)
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
close(0);
close(2);
int fd = open("file",O_RDONLY,0644);//以只读方式打开
if(fd < 0)
{
perror("open");
return 1;//程序失败
}
int fd1 = open("file1",O_RDONLY,0644);
int fd2 = open("file2",O_RDONLY,0644);
int fd3 = open("file3",O_RDONLY,0644);
printf("fd : %d\n",fd);
printf("fd : %d\n",fd1);
printf("fd : %d\n",fd2);
printf("fd : %d\n",fd3);
return 0;
}
因为‘1’没有关所以没有‘1’。
小结:
这里所有的函数必须用到文件描述符,文件描述符默认从‘0’开始分配,而实际上‘0’、‘1’、‘2’已经被占用,分别对应stdin(标准输入)、stdout(标准输出)、stderr(标准错误)。用户分配默认从‘3’开始
推荐阅读
-
(P4-P5)文件与IO:open、close、creat、read、write
-
Linux的系统调用open,write,read,close,及相关总结
-
文件相关系统调用接口open/write/read/close
-
open/read/write/close等文件系统调用接口说明
-
linux系统调用open、write、close、read以及stat函数详解
-
open/read/write/close等文件相关系统调用接口
-
open/read/write/close等文件系统调用接口以及fd与FILE的比较
-
简介几种系统调用函数:write、read、open、close、ioctl
-
linux gnu c 复制文件实例(open,close,creat,read,write)
-
Linux基础IO-系统调用接口open/read等&文件系统&软硬链接&静/动态库