• Linux中的文件IO



    重点学习内容:

       1)什么是文件IO

      2)文件操作的主要接口API

      3)文件操作的一般步骤

      4)文件操作的一些概念

      5)什么是文件描述符及其作用

      6)一个简单的文件读写实例

    1、什么是文件IO

      IO就是input/output,输入/输出。文件IO的意思就是读写文件。也称文件IO称之为不带缓存的IO(unbuffered I/O)。

    2、文件操作的主要接口API

      API(Application Programming Interface),应用程序编程接口函数

      Linux常用文件IO接口 open、close、write、read、lseek,我们可以使用man 手册来查询每个函数的使用方法,返回值,传参等等。

    man 2 open
    man 2 read
    man 2 write
    man 2 lseek
    man 2 close
    int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
    ssize_t read(int fd, void *buf, size_t count);
    ssize_t write(int fd, const void *buf, size_t count);
    off_t lseek(int fd, off_t offset, int whence);
    int close(int fd);

    如下图open函数:

    3、文件操作的一般步骤

      1)先open打开一个文件,得到一个文件描述符

      2)然后对文件进行读写操作(或其他操作)

      3)最后close关闭文件

    4、文件操作的一下概念

      1)文件平时是存在块设备中的文件系统中的,我们把这种文件叫静态文件

      2)将静态文件的内容从块设备中读取到内存中特定地址管理存放(叫动态文件)

      3)当我们去open打开一个文件时,linux内核做的操作包括:内核在进程中建立了一个打开文件的数据结构,记录下我们打开的这个文件;内核在内存中申请一段内存存放打开的文件。 之后对这个文件的读写操作,都是针对内存中这一份动态文件的,而并不是针对静态文件的。我们对动态文件进行读写后,此时内存中的动态文件和块设备中的静态文件就不同步了,当我们close关闭动态文件时,close内部内核将内存中的动态文件的内容去更新(同步)块设备中的静态文件。

    5、什么是文件描述符及其作用

      1) 文件描述符就是用来区分一个程序打开的多个文件的。

      2) 文件描述符的作用域就是当前进程,出了当前进程这个文件描述符就没有意义了。

    6、一个简单的文件读写实例

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    #define FILENAME "a.txt"
    
    int main(void)
    {
        int fd = -1;
        int Wfd = 0;
        int Rfd = 0;
        char Writebuff[13]={"I_love_Linux!"};
        char Readbuff[100]={0};
            
        // int open(const char *pathname, int flags);
        fd = open(FILENAME,O_RDWR);
        if(fd < 0)
        {
            perror("open");
            return 0;
        }
        //ssize_t write(int fd, const void *buf, size_t count);
        Wfd = write(fd,Writebuff,13);
        if(Wfd < 0)//写入失败
        {
            perror("write");
            return 0;
        }
        printf("写入了%d 个数据
    ",Wfd);
        //sleep(1);
        //ssize_t read(int fd, void *buf, size_t count);
        Rfd = read(fd,Readbuff,13);
        if(Rfd < 0)
        {
            perror("read");
            return 0;
        }
        printf("读取了%d 个数据
    ",Rfd);
        printf("读取到的数据为%s 
    ",Readbuff);
        
        close(fd);
        
        return 0;
    }

    这个代码单独读或单独写都没有问题,但是连接起来先写入再来读取就不行,运行结果如下:

    读取成功了,但是却为0,很是纳闷,我们明明是O_RDWR 可读可写模式就是不行,但是发现读在写的前面,写是可以成功的,如下图:

    但是还是有点奇怪,他居然是追加的写到了原有数据的后面,我们并没有设置追加写入O_APPEND,

    对于问题:先写入再读取为0,和先读取再写入变成追加模式

    最后测试发现写完数据或读完数据就关闭文件,然后再open打开再去读取数据或或写入数据就OK了。

    个人理解为当你写入文件时没有保存文件(即没执行close(fd))这个时候去读取数据肯定是空的,即出现读取数据为0,而对于先读取数据时,数据已经在一个读取的状态了没法覆盖所以就形成了追加模式

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <unistd.h>
    
    #define FILENAME "a.txt"
    
    int main(void)
    {
        int fd = -1;
        int Wfd = 0;
        int Rfd = 0;
        char Writebuff[13]={"fffffffffffff"};
        char Readbuff[100]={0};
            
        // int open(const char *pathname, int flags);
        fd = open(FILENAME,O_RDWR);
        if(fd < 0)
        {
            perror("open");
            return 0;
        }
        //ssize_t write(int fd, const void *buf, size_t count);
        Wfd = write(fd,Writebuff,13);
        if(Wfd < 0)//写入失败
        {
            perror("write");
            return 0;
        }
        printf("写入了%d 个数据
    ",Wfd);
        close(fd);
        fd = open(FILENAME,O_RDWR);
        if(fd < 0)
        {
            perror("open");
            return 0;
        }
        //ssize_t read(int fd, void *buf, size_t count);
        Rfd = read(fd,Readbuff,13);
        if(Rfd < 0)
        {
            perror("read");
            return 0;
        }
        printf("读取了%d 个数据
    ",Rfd);
        printf("读取到的数据为%s 
    ",Readbuff);
    
        close(fd);
        
        return 0;
    }

    这个就可以实现边写边读取,对于先读后写修改一下就可以了。

  • 相关阅读:
    BZOJ 1266: [AHOI2006]上学路线route
    重磅!阿里云Promtheus 正式免费公测
    解锁云原生 AI 技能|在 Kubernetes 上构建机器学习系统
    更新与发展 | Alibaba Cloud Linux 2 特性与开发细节揭秘
    《2019上半年DDoS攻击态势报告》发布:应用层攻击形势依然严峻,海量移动设备成新一代肉鸡
    《2019年上半年Web应用安全报告》发布:90%以上攻击流量来源于扫描器,IP身份不再可信
    并发模式与 RPS 模式之争,性能压测领域的星球大战
    互联网商城的上云改造之旅
    技术人具备“结构化思维”意味着什么?
    弘康人寿基于 RocketMQ 构建微服务边界总线的实践
  • 原文地址:https://www.cnblogs.com/ncne/p/10982586.html
Copyright © 2020-2023  润新知