常用的文件操作接口

1 文件描述符和打开模式

1.1 文件描述符

文件描述符fd:

  • 是一个>=0的整数。
  • 每打开一个文件,就创建一个文件描述符,通过文件描述符来操作文件。

预定义的文件描述符:

  • 0:标准输入,对应于已打开的标准输入设备(键盘)
  • 1:标准输出,对应于已打开的标准输出设备(控制台)
  • 2:标准错误, 对应于已打开的标准错误输出设备(控制台)

多次打开同一个文件,可得到多个不同的文件描述符。

fd本质为特殊的索引,实际上就是进程中file_struct结构体成员fd_array的数组下标。

在这里插入图片描述

1.2 文件打开模式

主模式:

  • O_RDONLY:只读模式
  • O_WRONLY:只写模式
  • O_RDWR:读写,模式

副模式:

  • O_CREAT:当文件不存在,需要去创建文件
  • O_APPEND:追加模式
  • O_DIRECT:直接IO模式
  • O_SYNC:同步模式
  • O_NOBLOCK:非阻塞模式
  • O_EXCL:如果同时使用O_CREAT而且该文件又已经存在时,则返回错误, 用途:以防止多个进程同时创建同一个文件
  • O_TRUNC:若文件存在,则长度被截为0,属性不变

2 open

头文件:

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

函数原型:

  • 当文件存在时

    int open(const char* pathname,int flags)
    
  • 当文件不存在时

    int open (const char* pathname,int flags,int perms)
    

上面的两个函数实际上是使用可变参数。
当其第二个参数含有O_CREAT 时,第三个参数才有效。表示的是当使用open系统调用创建一个文件时,其文件的访问权限是多少,第三个参数可以指定为0755,0644等,也可以用系统提供的宏:S_IRWXU、S_IRUSR等代替,一个作用。

返回值:

  • 成功:文件描述符
  • 失败:-1

注意:返回的文件描述符是该进程未打开的最小的文件描述符。


3 close

头文件:

#include <unistd.h>

函数原型:

int close(int fd)

返回值:

  • 成功:0
  • 失败:-1

4 read

头文件:

#include <unistd.h>

函数原型:

ssize_t read(int fd,void *buff,size_t count)		// ssize_t是有符号数

返回值:

成功:

  • count:成功读取全部字节
  • 0~count:
    • 剩余文件长度小于count
    • 读取期间被异步信号打断

失败:

  • -1,读取错误

5 write

头文件:

#include <unistd.h>

函数原型:

ssize_t write(int fd,void *buff,size_t count)

返回值:

成功:

  • count:成功写入全部字节
  • 0~count:
    • 写入期间被异步信号打断

失败:

  • -1,读取错误

复制普通文件小实验:

1、打开要复制的文件

2、创建新的文件

3、把源文件内容读到缓冲区,把缓冲区内容写入新文件

4、循坏执行第三步,直到读取的字节数量为0,退出循坏。

5、关闭打开的文件

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

int main(int argc, char* argv[])
{
    int fd1 = -1, fd2 = -1;
    int read_len = 0;
    char buffer[512] = {0};
    
    if (argc != 3)
    {
        printf("error usage !\n");
        return -1;
    }

    fd1 = open(argv[1], O_RDONLY);
    fd2 = open(argv[2], O_WRONLY | O_CREAT, 0666);

    if ((fd1 < 0) || (fd2 < 0))
    {
        close(fd1);
        close(fd2);
        printf("open file error!\n");
        return -1;
    }

    while (1)
    {
        read_len = read(fd1, buffer, sizeof(buffer));

        if (read_len <= 0)
        {
            break;
        }

        write(fd2, buffer, read_len);
    }

    close(fd1);
    close(fd2);

    return 0;
}


6 lseek

功能:

  • 设置文件读写位置

头文件:

#include <unistd.h>

函数原型:

off_t lseek(int fd,off_t offset,int whence)
  • 若whence为SEEK_SET,基准点为文件开头
  • 若whence为SEEK_CUR,基准点为当前位置
  • 若whence为SEEK_END,基准点为文件末尾

返回值:

  • 成功:文件偏移位置值
  • 失败:-1

读写是使用的同一个位置指针。使用O_RDWR时,如果先读了一段再写,那么写的位置从读完处开始,同理先写了一段再读,那么读的位置从写完处开始。可以使用lseek来改变文件位置指针,即读写的位置。


7 sync

在这里插入图片描述

功能:

  • 页缓存和回写,强制把修改过的页缓存区数据写入磁盘。

头文件:

#include <unistd.h>

函数原型:

void sync(void);

返回值:


8 标准IO函数

由于系统文件IO函数需要在用户态和内核态之间进行切换,所以效率比较低。标准IO则在应用层实现了一个缓冲区,示意图如下:
在这里插入图片描述

常见标准IO函数:

  • fopen

  • fclose

  • fread

  • fwrite

  • fseek

  • fflush:强制把IO缓存区的数据写入到页缓存区

文件IO五大模式:

  • 阻塞模式
  • 非阻塞模式
  • IO多路复用
  • 异步IO
  • 信号驱动IO

参考资料:

  1. [野火]i.MX Linux开发实战指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值