Linux操作系统:IO基础-文件I/O

前言

文件I/O又称为低级磁盘I/O,遵循POSIX相关标准。在Linux系统中所有的I/O 操作是通过读文件以及写文件的方式来完成的。通过文件I/O读写文件时,每次操作都会执行相关系统调用。这样处理文件的好处是直接读写实际文件,坏处是频繁的系统调用会增加系统开销。文件I/O中用文件描述符表示一个打开的文件,可以访问不同类型的文件,如普通文件、设备文件和管道文件等。

文件描述符

文件描述符是一个非负的整数,它是一个索引值,并指向在内核中每个进程打开文件的记录表。通常,一个进程启动时,都会打开3个流:标准输入、标准输出和标准出错。这3个流分别对应文件描述符0、1和2(对应的宏分别是STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO)

文件I/O相关函数

操作文件的步骤:

                        打开文件

                        操作文件(读/写)

                        关闭文件

1.打开文件(open()函数)

头文件:        #include <sys/types.h>

                      #include <sys/stat.h>

                      #include <fcntl.h>

1.1(两个参数)

函数原型: int open(const char *pathname, int flags);

功能:用于打开一个指定的文件

参数1:文件名(带路径)

参数2:打开的文件方式

 返回值:成功返回值为非负的整数(文件描述符)

               失败返回-1

1.2(三个参数)

函数原型:int open(const char *pathname, int flags, mode_t mode);

功能:用于打开一个指定的文件                  

参数1:文件名(带路径)                     

参数2:打开的文件方式                

参数3:一般新建文件的时候,需要第三个参数为其设置权限

 返回值:成功返回值为非负的整数(文件描述符)

               失败返回-1

打开方式: 

以下三种方式必须其一

                                        O_RDONLY:以只读的方式打开文件

                                        O_WRONLY:以只写的方式打开文件

                                        O_RDWR:以可读可写的方式打开文件

其余的,和上面进行或运算

                                        O_CREAT:如果文件不存在,则新建,但同时必须使用第三个参数

                                        O_EXCL:如果文件存在则出错

                                   O_NOCTTY: 使用本参数时,若文件为终端,那么该终端不可以作为调用open()系统调用的那个进程的控制终端。

                              O_TRUNC:如文件已经存在,那么打开文件时先删除文件中原有数据。                                        

                                      O_APPEND:以添加方式打开文件,如果文件存在则追加在文件的末尾。

2.关闭文件(close()函数)

头文件:#include <unistd.h>

函数原型:int close(int fd);

参数:open函数的返回值,已经打开的文件描述符

返回值:成功返回0,失败返回-1

例:

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

int main()
{
    int fd;
    if((fd = open("text.txt",O_RDONLY | O_WRONLY | O_CREAT,0666)) <0)
    {
         perror("open error");
         return -1;   
    }
    close(fd);
    return 0;
}

3.操作文件(读写操作)

3.1read()函数

头文件: #include <unistd.h>

函数原型:ssize_t read(int fd, void *buf, size_t count);

功能:从指定的文件中读取内容

参数1:文件描述符

参数2:存储读取到的内容的空间首地址

参数3:指定要读的字节数

返回值:成功:读取到的字节个数(大于0)

               失败:返回值为-1

               等于0代表读取到文件末尾了

3.2write()函数

头文件:#include <unistd.h>

函数原型:ssize_t write(int fd, const void *buf, size_t count);

功能:给指定的文件中写入内容

参数1:文件描述符

参数2:存储需要被写入的内容所在的空间的首地址

参数3:指定要写的字节数

返回值: 成功:写入文件的的字节个数(大于0)

               失败:返回值为-1

               等于0代表此时未写入

例:文件的拷贝

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

int main(int argc,char *argv[])
{
    //入参判断
    if(argc < 3)
    {
        printf("please try again!\n");
        return -1;
    }
    //打开文件
    //打开要读取的文件
    int fr = open(argv[1],O_RDONLY);
    if(fr < 0)
    {
        perror("open fr error");
        return -1;
    }
    //打开要写入的文件
    int fw = open(argv[2].O_WRONLY | O_CREAT,0664);
    if(fw < 0)
    {
        perror("open fw error");
        return -1;
    }
    char buf[1024] = {0};
    while(1)
    {
        int ret = read(fr,buf,sizeof(buf));
        if(0 == ret)
        {
            break;
        }    
        else if(ret < 0)
        {
            printf("读取文件失败\n");
        }
        write(fw,buf,sizeof(buf));
    }
    //关闭文件
    close(fr);
    close(fw);
    return 0;
}

3.3其他函数

头文件:#include<sys/types.h>

               #include<unistd.h>

函数原型:off_t lseek(int fd, off_t offset, int whence);

参数1:文件描述符

参数2:偏移量

参数3:偏移的位置

SEEK_SET:从文件开头

SEEK_CUR:从当前位置

SEEK_END:从文件末尾

返回值:成功返回文件当前读写位置

                失败返回-1

例:空洞文件

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

int main(int argc,char *argv[])
{
    //入参判断
    if(argc < 2)
    {
        printf("输入有误!\n");
        return -1;
    }
    //打开文件
    int fw = open(argv[1],O_WRONLY | O_CREAT,0664);
    if( fw < 0 )
    {
        perror("open error");
        return -1;
    }
    //操作文件
    lseek(fw,1024*1024*1024,SEEK_SET);
    write(fw,"\0",1);
    //关闭文件
    close(fw);
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是 Linux 内核源码中 ext4 文件系统部分的代码。 该目录下包含了 ext4 文件系统的核心代码,包括: 1. super.c:superblock 相关代码,用于管理文件系统的元数据信息。 2. inode.c:inode 相关代码,用于管理文件和目录的元数据信息。 3. namei.c:namei 相关代码,用于管理文件和目录的路径信息。 4. file.c:file 相关代码,用于管理文件和目录的读写操作。 5. dir.c:directory 相关代码,用于管理目录的读写操作。 6. extents.c:extent 相关代码,用于管理文件和目录的数据块分配和释放。 7. mballoc.c:multi-block allocator 相关代码,用于管理文件和目录的空间分配和释放。 8. resize.c:resize 相关代码,用于管理文件系统的扩容和缩容操作。 此外,还包括一些与 ext4 文件系统相关的辅助函数和工具函数,例如: 1. balloc.c:block allocator 相关代码,用于管理文件系统的数据块分配和释放。 2. bitmaps.c:bitmap 相关代码,用于管理文件系统的位图信息。 3. checksum.c:checksum 相关代码,用于管理文件系统的校验和计算。 4. extents_status.c:extent status 相关代码,用于管理文件系统的数据块状态信息。 5. migrate.c:migration 相关代码,用于管理文件系统的数据块迁移操作。 6. page-io.c:page I/O 相关代码,用于管理文件系统的页缓存和 I/O 操作。 7. sysfs.c:sysfs 相关代码,用于管理文件系统的 sysfs 接口。 8. utils.c:utility 相关代码,用于提供一些常用的工具函数。 每个文件都有相应的注释,用于描述该文件的作用和实现细节。整个代码库的结构清晰,代码风格规范,是学习文件系统实现的优秀范例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值