操作系统实验-与文件读写有关的系统调用函数用法
1、open函数
点击查看代码
#include <fcntl.h> //头文件
int open(const char *pathname, int flags, mode_t mode);
pathname: 要打开文件的路径名;
flags:用于指定文件的打开方式和行为,以下是一些常见的标志,都通过宏进行了定义;
O_RDONLY:只读方式打开文件。
O_WRONLY:只写方式打开文件。
O_RDWR:读写方式打开文件。
O_CREAT:如果文件不存在,则创建文件。
O_APPEND:在文件末尾追加数据。
mode:用于指定新创建的权限,仅在O_CREATE时有效。必须是8进制形式,C语言中八进制以数字0开头,每一个八进制数对应三位二进制,从高位到低位分别对应rwx(读写执行),如0644分别对应所有者有rw-权限,所属组有-w-权限,其它成员有-w-权限
函数返回一个文件描述符,是一个非负整数,如果返回值为负数,说明发生了错误
有关文件描述fd为什么是非负整数及其底层原理,可以参考链接:https://zhuanlan.zhihu.com/p/364617329
返回值:返回文件的文件操作符,对所打开的文件执行读写和关闭操作就需要通过这个文件操作符来进行
2、read函数
点击查看代码
#include <unistd.h> //头文件
ssize_t read(int fd, void *buf, size_t count);
read函数从已打开的文件中读取数据,并将其存储到缓冲区buf中。它接受三个参数:
fd:已打开文件的文件描述符。
buf:用于存储读取数据的缓冲区。
count:要读取的字节数。
read函数返回实际读取的字节数。如果返回值为0,表示已到达文件末尾。如果返回值为负数,表示发生了错误
3、wite函数
点击查看代码
#include <unistd.h> //头文件
ssize_t write(int fd, const void *buf, size_t count);
fd:已打开文件的文件描述符。
buf:要写入文件的数据缓冲区。
count:要写入的字节数。
返回值:返回实际写入的字节数,如果返回值为负数,表示发生了错误
4、lseek函数
点击查看代码
#include <unistd.h> //头文件
off_t lseek(int fd, off_t offset, int whence);
用于在已经打开的文件中移动文件指针的位置
fd:已打开文件的文件描述符。
offset:指定文件指针移动的偏移量。
whence:指定偏移量的基准位置,可以是以下值之一:
SEEK_SET:从文件开头开始计算偏移量。
SEEK_CUR:从当前文件指针位置计算偏移量。
SEEK_END:从文件末尾开始计算偏移量。
返回值:返回文件指针移动后的位置,如果返回值为负数,表示发生了错误
5、close函数
点击查看代码
#include <unistd.h> //头文件
int close(int fd);
用于关闭已打开的文件
fd:要关闭的文件描述符。
返回值:返回一个整数值,如果返回值为0,表示关闭文件成功,如果返回负数,表示发生错误
踩坑记录
对于open函数,它的属性要考虑清楚,比如读写,是否截断等属性
每次write向文件写入后都会移动文件指针,要想用read正确读取文件内容,需要使用lseek改变文件指针
文件指针是以字节为单位,直接向文件中写入数字而不是字符的话,打开文件看到的是乱的东西,但是使用read能够正确读,要想打开文件也能看到正常的东西,需要转换为字符再写入
以下使用上述函数进行读写的一个示例代码:
点击查看代码
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int fd = open("buffer.txt", O_RDWR | O_CREAT | O_TRUNC, 0644);
//O_RDWR | O_CREAT | O_TRUNC表示设置为读写,文件不存在时创建,每次打开时如果文件已存在就清空文件所有内容
for(int i = 0; i < 500; i++)
{
ssize_t count = write(fd, &i, sizeof(int));
if(count > 0)
{
printf("write %d ", i);
}
else
{
printf("erro!\n");
return 0;
}
}
printf("\n");
int read_out = -1;
/*必须移动指针到正确位置才能正确读取,因为每次写入后文件指针都会移动
并且指针的移动以字节为单位
比如这里写入的时候每个整数占据sizeof(int)个字节的位置
那么要读取2就要移动2 * sizeof(int)
*/
lseek(fd, 100 * sizeof(int), SEEK_SET);
read(fd, &read_out, sizeof(int));
printf("read_out = %d\n", read_out);
close(fd);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!