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;
}

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

原文地址:https://www.cnblogs.com/ncne/p/10982586.html