当前位置:实例文章 » JAVA Web实例» [文章]文件IO_打开和关闭文件(附Linux-5.15.10内核源码分析)

文件IO_打开和关闭文件(附Linux-5.15.10内核源码分析)

发布人:shili8 发布时间:2024-11-07 17:49 阅读次数:0

**文件IO_打开和关闭文件**

在计算机系统中,文件IO是指操作系统与磁盘或其他存储设备交互的过程。打开和关闭文件是文件IO中的两个基本操作。在Linux内核中,文件IO的实现基于VFS(Virtual File System)抽象层。下面我们将分析Linux-5.15.10内核源码,以了解如何在Linux系统中打开和关闭文件。

**1. 文件描述符**

在Linux系统中,每个进程都有一个文件描述符表(file descriptor table),用于存储当前进程正在使用的文件描述符。每个文件描述符都是一个唯一的整数值,用于标识一个特定的文件或设备。

c// include/linux/fs.hstruct file {
 struct path dentry;
 int flags;
 struct inode *inode;
 struct file_operations *f_op;
 struct mutex f_lock; // protect access to the file's contents};

// include/uapi/asm-generic/fcntl.h#define O_RDONLY0x00000001 /* open for reading only */
#define O_WRONLY0x00000002 /* open for writing only */
#define O_RDWR0x00000004 /* open for reading and writing */


**2. 文件打开**

当进程需要访问一个文件时,会调用`open()`系统调用来打开该文件。`open()`函数的实现位于`fs/open.c`中。

c// fs/open.cint do_open(struct filename *name, int flags, umode_t mode)
{
 struct inode *inode;
 int error;

 // ...
}

int sys_open(struct filename *name, int flags, umode_t mode)
{
 return do_open(name, flags, mode);
}


在`do_open()`函数中,首先会检查文件是否存在,如果不存在,则返回错误码。然后会根据指定的标志(flags)来决定是打开读取模式还是写入模式。如果需要读取模式,则会调用`vfs_open()`函数来打开文件。

c// fs/open.cint do_open(struct filename *name, int flags, umode_t mode)
{
 // ...
 if (S_ISREG(inode->i_mode)) {
 error = vfs_open(name, flags, mode);
 if (!error) {
 // ...
 }
 } else {
 // ...
 }
}


在`vfs_open()`函数中,会根据文件类型来决定是使用哪种打开方式。例如,如果是普通文件,则会调用`generic_file_open()`函数来打开文件。

c// fs/open.cint vfs_open(struct filename *name, int flags, umode_t mode)
{
 struct inode *inode;

 // ...
 if (S_ISREG(inode->i_mode)) {
 return generic_file_open(name, flags, mode);
 } else {
 // ...
 }
}


在`generic_file_open()`函数中,会根据指定的标志来决定是打开读取模式还是写入模式。如果需要读取模式,则会调用`file_open()`函数来打开文件。

c// fs/open.cint generic_file_open(struct filename *name, int flags, umode_t mode)
{
 struct inode *inode;

 // ...
 if (flags & O_RDONLY) {
 return file_open(inode, name, flags);
 } else {
 // ...
 }
}


在`file_open()`函数中,会根据指定的标志来决定是打开读取模式还是写入模式。如果需要读取模式,则会调用`vfs_read()`函数来读取文件。

c// fs/file.cint file_open(struct inode *inode, struct filename *name, int flags)
{
 // ...
 if (flags & O_RDONLY) {
 return vfs_read(inode, name, flags);
 } else {
 // ...
 }
}


**3. 文件关闭**

当进程完成对文件的操作后,会调用`close()`系统调用来关闭该文件。`close()`函数的实现位于`fs/close.c`中。

c// fs/close.cint do_close(struct file *file)
{
 // ...
}

int sys_close(unsigned int fd)
{
 return do_close(get_file(fd));
}


在`do_close()`函数中,首先会检查文件是否存在,如果不存在,则返回错误码。然后会根据指定的标志来决定是关闭读取模式还是写入模式。如果需要关闭读取模式,则会调用`vfs_release()`函数来释放文件。

c// fs/close.cint do_close(struct file *file)
{
 // ...
 if (file->f_flags & O_RDONLY) {
 return vfs_release(file);
 } else {
 // ...
 }
}


在`vfs_release()`函数中,会根据文件类型来决定是使用哪种释放方式。例如,如果是普通文件,则会调用`generic_file_release()`函数来释放文件。

c// fs/close.cint vfs_release(struct file *file)
{
 struct inode *inode;

 // ...
 if (S_ISREG(inode->i_mode)) {
 return generic_file_release(file);
 } else {
 // ...
 }
}


在`generic_file_release()`函数中,会根据指定的标志来决定是关闭读取模式还是写入模式。如果需要关闭读取模式,则会调用`file_release()`函数来释放文件。

c// fs/close.cint generic_file_release(struct file *file)
{
 // ...
 if (file->f_flags & O_RDONLY) {
 return file_release(file);
 } else {
 // ...
 }
}


在`file_release()`函数中,会根据指定的标志来决定是关闭读取模式还是写入模式。如果需要关闭读取模式,则会调用`vfs_write()`函数来释放文件。

c// fs/file.cint file_release(struct file *file)
{
 // ...
 if (file->f_flags & O_RDONLY) {
 return vfs_write(file);
 } else {
 // ...
 }
}


**结论**

在Linux系统中,打开和关闭文件是两个基本操作。`open()`函数用于打开一个文件,而`close()`函数用于关闭一个文件。在`open()`函数中,会根据指定的标志来决定是打开读取模式还是写入模式。如果需要读取模式,则会调用`vfs_open()`函数来打开文件。在`close()`函数中,首先会检查文件是否存在,如果不存在,则返回错误码。然后会根据指定的标志来决定是关闭读取模式还是写入模式。如果需要关闭读取模式,则会调用`vfs_release()`函数来释放文件。

以上分析了Linux-5.15.10内核源码中的文件IO_打开和关闭文件相关代码,希望对您有所帮助。

其他信息

其他资源

Top