Linux/Unix中系统级IO

Linux/unix I/O将设备映射为文件的方式,允许Unix内核引出一个简单、低级的应用接口。

 Linux/unix IO的系统调用函数很简单,它只有5个函数:open(打开)、close(关闭)、read(读)、write(写)、lseek(定位)。但是系统IO调用开销比较大,一般不会直接调用,而是通过调用Rio包进行健壮地读和写,或者调用C语言的标准I/O进行读写。尽管如此,Rio包和标准IO也都是封装了unix I/O的,所以学习系统IO的调用才能更好地理解高级IO的原理。

1、打开文件 返回一个小的非负整数,即描述符。用描述符来标识文件。每个进程都有三个打开的文件:标准输入(0)、标准输出(1)、标准错误(2

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(char *filename, int flags, mode_t mode);
        //返回:若成功则为新文件描述符,若出错为-1

flags:进程打算如何访问文件

O_RDONLY:只读    O_WRONLY:只写    O_RDWR:可读可写

也可以是一个或更多位掩码的或:

O_CREAT:如文件不存在,则创建

O_TRUNC:如果文件已存在,则截断

O_APPEND:每次写操作,设置k到文件结尾

mode:指定新文件的访问权限位

每个进程都有一个umask,通过调用umask函数设置。所以文件的权限为被设置成mode & ~umask

2、改变当前文件位置  从文件开头起始的字节偏移量。系统内核保持一个文件位置k,对于每个打开的文件,起始值为0。应用程序执行seek,设置当前位置k,通过调用lseek函数,显示地修改当前文件位置。

3、读写文件。读操作:从文件拷贝n个字节到存储器,从当前文件位置k开始,将k增加到k+n,对于一个大小为m字节的文件,当k>=m时,读操作触发一个EOF的条件。写操作:从存储器拷贝n个字节到文件,k更新为k+n

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t n);
            //返回:若成功则为读的字节数,若EOF则为0,若出错为-1.

ssize_t write(int fd, const void *buf, size_t n);
            //返回:若成功则为写的字节数,若出错则为-1.

 

read函数:从描述符为fd的当前文件位置拷贝至多n个字节到存储器位置buf。返回-1表示一个错误,返回0表示EOF,否则返回实际读取的字节数。

write函数:从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。

 

Ps:ssize_tsize_t区别:size_tunsigned intssized_tint

4、关闭文件:内核释放文件打开时创建的数据结构,并恢复描述符到描述符池中,进程通过调用close函数关闭一个打开的文件。关闭一个已关闭的描述符会出错。

#include <unistd.h>

int close(int fd);
                //返回:若成功则为0,若出错则为-1.

 

posted @   牛逼的码农  阅读(654)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端
点击右上角即可分享
微信分享提示