主页 > IT业界  > 

文件IO、目录IO

文件IO、目录IO

在 Linux 内核中,文件 I/O(输入/输出)操作涉及一组系统调用,这些调用是用户空间程序与内核空间文件系统之间的接口。常见的文件 I/O 操作包括 open()、read()、write()、lseek() 等,这些系统调用提供了访问文件、读取文件内容、写入数据和操作文件指针等功能。

1. open() 系统调用 open() 用于打开一个文件或者创建一个文件,并返回文件描述符(file descriptor)。它的原型如下:

int open(const char *pathname, int flags, mode_t mode);

pathname:文件路径。 flags:打开文件的方式,常见的标志有: O_RDONLY:只读模式 O_WRONLY:只写模式 O_RDWR:读写模式 O_CREAT:文件不存在时创建 O_APPEND:以追加模式打开文件 O_TRUNC:文件存在时截断为0大小 mode:如果文件被创建(O_CREAT 标志),则指定文件的权限(如 S_IRUSR, S_IWUSR 等)。 open() 函数返回一个非负整数的文件描述符(文件句柄),如果出错,则返回 -1。

内核实现: 在内核中,open() 系统调用通过 do_sys_open() 函数来实现。内核会根据 flags 参数判断如何打开文件,并调用具体的文件系统接口来完成文件的打开操作。

2. read() 系统调用 read() 用于从文件中读取数据。它的原型如下:

ssize_t read(int fd, void *buf, size_t count);

fd:文件描述符,由 open() 返回。 buf:指向存储读取数据的缓冲区。 count:要读取的字节数。 read() 会返回实际读取的字节数,如果遇到文件末尾(EOF),返回 0;出错时返回 -1。

内核实现: 在内核中,read() 会调用对应文件系统的 read() 方法,通常是通过 vfs_read() 函数。这会先查找文件系统的相关操作,然后读取数据并将其拷贝到用户空间缓冲区。

3. write() 系统调用 write() 用于向文件写入数据。它的原型如下:

ssize_t write(int fd, const void *buf, size_t count);

fd:文件描述符,由 open() 返回。 buf:指向包含要写入数据的缓冲区。 count:要写入的字节数。 write() 返回实际写入的字节数。如果出现错误,返回 -1。

内核实现: 在内核中,write() 系统调用通过 vfs_write() 函数来实现。具体的文件系统会根据需要将数据写入磁盘,操作涉及到文件缓存管理和磁盘 I/O。

4. lseek() 系统调用 lseek() 用于改变文件的读取/写入位置。它的原型如下:

off_t lseek(int fd, off_t offset, int whence);

fd:文件描述符。 offset:偏移量。 whence:如何解释偏移量,常见的值有: SEEK_SET:从文件的开头开始偏移。 SEEK_CUR:从当前位置偏移。 SEEK_END:从文件末尾偏移。 lseek() 返回新的文件位置(以字节为单位)。如果出错,返回 -1。

内核实现: 在内核中,lseek() 系统调用通过 vfs_llseek() 来实现,它会根据文件的类型和文件系统的不同来处理文件偏移操作。对于普通文件,它会更新文件的文件指针;对于某些特殊文件(如设备文件),lseek() 可能会有不同的实现。

5. 文件 I/O 的文件系统层 在内核中,文件系统通过一组虚拟文件系统(VFS)接口来管理文件。VFS 是一个抽象层,允许不同的文件系统(如 ext4、xfs、ntfs 等)通过统一的接口进行操作。VFS 提供了很多与文件操作相关的函数,如 vfs_read()、vfs_write()、vfs_open() 等。

内核中文件 I/O 相关的主要结构和函数: file_operations 结构体:包含一组指向操作函数的指针,如 read(), write(), open(), release() 等。这些函数处理文件的具体操作。 inode 结构体:表示文件的元数据,如文件类型、权限、大小等。 file 结构体:表示文件描述符,包含文件指针等信息。 dentry 结构体:表示目录项,用于目录的遍历。 文件 I/O 流程概述: 打开文件:

用户调用 open() 系统调用。 内核通过 vfs_open() 查找文件并返回文件描述符。 读取文件:

用户调用 read() 系统调用。 内核通过 vfs_read() 获取数据并拷贝到用户空间。 写入文件:

用户调用 write() 系统调用。 内核通过 vfs_write() 将数据写入文件系统。 调整文件指针:

用户调用 lseek() 系统调用。 内核通过 vfs_llseek() 调整文件的读写位置。 总结 open():打开文件,返回文件描述符。 read():从文件读取数据。 write():向文件写入数据。 lseek():调整文件的读写位置。

标签:

文件IO、目录IO由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“文件IO、目录IO