文件操作:
底层系统调用:
所需头文件:
#include<fcntl.h>
int open(文件路径(const char *),打开方式(只读,只写,读写,创建),文件权限):
其中打开方式:
只读:O_RDONLY
只写:O_WRONLY
读写:O_RDWR
创建:O_CREAT
文件权限:
当要打开的文件不存在时,才会写第三个参数,0600(读写权限)
返回值:
返回值为文件描述符(int)
int read(文件描述符(int),要读到写入的空间(void *),读取个数(int)):
返回值:
返回值为实际读到的字节个数
int write(文件描述符(int),要照着写入文件描述符文件的空间(void *),要写入的个数(int)):
int close(文件描述符(int)):
示例1:
先创建file.txt并写入hello
![](https://i-blog.csdnimg.cn/blog_migrate/2ebd2da44341a2ff6a8cd6d8c554d163.png)
再从file.txt中读取数据:
![](https://i-blog.csdnimg.cn/blog_migrate/b9dba7779bce52cab3b8dfd47a459e3b.png)
运行结果(打印read返回值,并打印读取内容)
![](https://i-blog.csdnimg.cn/blog_migrate/e8fd2473b2e161b162c63052989b3486.png)
示例2:
将一个图片读取并重新写为另一个图片(112.jpg读取并写入200.jpg)
![](https://i-blog.csdnimg.cn/blog_migrate/3ff9da1d00be694a0f2d2a1efcdcfedf.png)
![](https://i-blog.csdnimg.cn/blog_migrate/29439de313d21180c2a995fd41c6b2fb.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/33191b325b4ca5ca5e7fe66c0f06b572.png)
fork与文件操作:
![](https://i-blog.csdnimg.cn/blog_migrate/dcce34961b9fb7cebba70492bf2c9209.png)
以文件file.txt为例:文件内容为abcdefgh
当我们先打开文件再fork:
![](https://i-blog.csdnimg.cn/blog_migrate/dbdf67886e23b95623fced01d5b794bd.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/dd56015ca00bd190e4dd289cce81e3f6.png)
我们可以看到子进程是在父进程后面跟着打印,说明父子进程共用一个文件偏移量。
结论:
![](https://i-blog.csdnimg.cn/blog_migrate/252dd4cea006a97dce841868221c2718.png)
当我们先fork再打开文件
![](https://i-blog.csdnimg.cn/blog_migrate/34c6eafddb74de15e726c151d6ec4df9.png)
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/dd6e841c9c75dff6d35899761fbad1c5.png)
这时我们可以看到父子进程打印的东西一样,说明他们各自有各自的文件偏移量。
结论:
![](https://i-blog.csdnimg.cn/blog_migrate/13b02bb36ca6e8b5acc32113f42646ce.png)
系统调用与库函数的区别:
系统调用的实现在系统内核中,属于内核空间。库函数的实现在函数库中,属于用户态。
![](https://i-blog.csdnimg.cn/blog_migrate/f8311b9fcb54383e673ec1db8487b699.png)