操作文件的系统调用
1、文件操作有关的系统调用
open()
read()
write()
close()
1)open()
int open(const char* pathname, int flags);//用于打开一个已存在的文件
int open(const char* pathname, int flags,mode_t mode);//用于新建一个文件,并设置访问权限
参数介绍:
- pathname:将要打开的文件路径和名称
- flags : 打开标志,如 O_WRONLY 只写打开
- O_RDONLY 只读打开
- O_RDWR 读写方式打开
- O_CREAT 文件不存在则创建
- O_APPEND 文件末尾追加
- O_TRUNC 清空文件,重新写入
- mode: 权限 如: “0600”
- 返回值: 为文件描述符
2)read()
ssize_t read(int fd, void* buf, size_t count);
参数介绍: - fd 对应打开的文件描述符
- buf 存放数据的空间
- count 计划一次从文件中读多少字节数据
- 返回值: 为实际读到的字节数
3)write()
ssize_t write(int fd, const void buf,size_t count);*
参数介绍: - fd 对应打开的文件描述符
- buf 存放待写入的数据
- count 计划一次向文件中写多少数据
4)close() - int close(int fd);
参数介绍:
18.fd 要关闭的文件描述符
2、文件描述符
在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件、目录文件、链接文件和设备文件。文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符。程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误。如果此时去打开一个新的文件,它的文件描述符会是3。
3.在一个文件里写入数据
在本目录中创建一个file.txt文件,并写入hello,代码如下:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<assert.h>
6 #include<fcntl.h>
7
8 int main()
9 {
10 int fd = open("file.txt",O_WRONLY|O_CREAT,0600);
11 assert( fd != -1);
12
13 write(fd,"hello",5);
14
15 close(fd);
16
17 exit(0);
18
19 }
编译运行,生成file.txt文件,查看file.txt文件
4、读一个文件
读取file.txt文件
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<assert.h>
6 #include<fcntl.h>
7
8 int main()
9 {
10
11 int fd = open("file.txt",O_RDONLY);
12 assert ( fd != -1 );
13
14 char buff[128] = {0};
15
16 int n = read(fd,buff,127);
17
18 printf("n = %d,buff = %s",n,buff);
19
20 close(fd);
21
22 exit(0);
23
24 }
编译运行
5.写一个程序完成对一个普通文件的复制(类似 cp 命令)
拷贝当前路径下的file.txt文件,拷贝到当前路径,名为file1.txt,查看file.txt文件内容。
编写test.c,代码如下:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<assert.h>
6 #include<fcntl.h>
7
8 int main()
9 {
10 int fdr = open("file.txt",O_RDONLY);
11 int fdw = open("file1.txt",O_WRONLY|O_CREAT,0600);
12
13 if( fdr == -1 || fdw == -1)
14 {
15 printf("文件打开失败!");
16 exit(0);
17 }
18
19
20 char buff[512] = {0};
21 int num = 0;//一次读多少
22 while((num = read(fdr,buff,512)) > 0)
23 {
24 write(fdw,buff,num);
25
26 }
27
28 close(fdr);
29 close(fdw);
30
31 exit(0);
32
33 }
编译运行
生成file1.txt文件
查看file1.txt文件内容
6、父进程先打开一个文件, fork 后子进程是否可以共享使用
1)在当前目录下创建一个file.txt文件,写入内容abcdefgh
2)编写代码,程序先打开file.txt文件,再调用fork()创建一个子进程,父进程和子进程都各自读两次文件,一次1个字符内容,观察结果,代码如下:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<assert.h>
5 #include<string.h>
6 #include<fcntl.h>
7
8 int main()
9 {
10 int fd = open("file.txt",O_RDONLY);
11 assert( fd != -1 );
12
13 pid_t pid = fork();
14 assert(pid != -1);
15
16 char buff[128] = {0};
17
18 if(pid == 0)
19 {
20 read(fd,buff,1);
21 printf("child,buff = %s\n",buff);
22 sleep(1);
23 read(fd,buff,1);
24 printf("child,buff = %s\n",buff);
25
26 }
27 else
28 {
29 read(fd,buff,1);
30 printf("parent,buff = %s\n",buff);
31 sleep(1);
32 read(fd,buff,1);
33 printf("parent,buff = %s\n",buff);
34
35 }
36 close(fd);
37 exit(0);
38 }
编译运行
分析运行结果发现,当父进程先打开文件再fork()生成一个子进程时,子进程是在父进程读文件的偏移量基础上开始读文件的。