【Linux学习】文件IO(2)

以下是关于Linux文件IO的介绍和基本使用,希望对您有所帮助。

如果我的文章让你感兴趣,可以点赞收藏关注一波。

作者:小海编程心语录-CSDN博客

 

目录

 

文件操作

1.open 打开文件

2.write 写文件

3.read 读文件

4.close 关闭文件

5.lseek 位置偏移量


文件操作

在 Linux 系统中要操作一个文件,需要先打开该文件,得到文件描述符,然后再对文件进行相应的读写操作(或其他操作),最后再关闭该文件。

1.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, mode_t mode);

函数参数和返回值含义如下:

  • pathname: 用于标识需要打开或创建的文件,可以包含路径(绝对路径或相对路径)
  • flags:调用 open 函数时需要提供的标志,这些标志使 用宏定义进行描述,传入 flags 参数时既可以单独使用某一 个标志,也可以通过位或运算(|) 将多个标志进行组合,这些标志介绍如下:

标志

用途

说明

O_RDONLY

以只读方式打开文件

这三个是文件访问权限标志,传入的flags 参数中必须要包含其中一种标志,而且只能包含一种,打开的文件只能按照这种权限来操作,譬如使用了 O_RDONLY 标志,就只能对文件进行读取操作,不能写操作

O_WRONLY

以只写方式打开文件

O_RDWR

以可读可写方式打开文件

O_CREAT

如果 pathname 参数指向的文件不存在则创建此文件

使用此标志时,调用 open 函数需要传入第 3 个参数 mode,参数 mode 用于指定新建文件的访问权限

O_DIRECTORY

如果 pathname 参数指向的不是一个目录,则调用 open 失败

O_EXCL

此标志一般结合 O_CREAT 标志一起使用,用于专门创建文件在 flags 参数同时使用到了 O_CREAT 和O_EXCL 标志的情况下,如果 pathname 参数指向的文件已经存在,则 open 函数返回错误

如果文件不存在则创建此文件,如果存在则返回错误

O_NOFOLLOW

如果 pathname 参数指向的是一个符号链接,将不对其进行解引用,直接返回错误

不加此标志情况下,如果 pathname参数是一个符号链接,会对其进行解引用

O_TRUNC

若文件存在,则长度被截为0,属性不变

注:open 函数的 flags 标志并不止这些,譬如 O_APPEND、 O_ASYNC、 O_DSYNC、 O_NOATIME、 O_NONBLOCK、 O_SYNC 等

  • mode:用于指定新建文件的访问权限,只有当 flags 参数中包含 O_CREAT 或 O_TMPFILE 标志 时才有效
  • 返回值:成功将返回文件描述符,失败将返回-1

2.write 写文件

//函数原型
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);

函数参数和返回值含义如下:

  • fd: 文件描述符,将进 行写操作的文件所对应的文件描述符传递给 write 函数
  • buf: 指定写入数据对应的缓冲区
  • count: 指定写入的字节数
  • 返回值:如果成功将返回写入的字节数(0 表示未写入任何字节),如果此数字小于 count 参数,这不 是错误,譬如磁盘空间已满,可能会发生这种情况;如果写入出错,则返回-1

注:默认情况下当前位置偏移量是 0,也就是指向了文件起始位置,当调用 read、 write 函数读写操作完成之后, 当前位置偏移量也会向后移动对应字节数,譬如当前位置偏移量为 1000 个字节处,调用 write()写入或 read()读取 500 个字节之后,当前位置偏移量将会移动到 1500 个字节处。

3.read 读文件

//函数原型
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);

函数参数和返回值含义如下:

  • fd: 文件描述符。与 write 函数的 fd 参数意义相同。
  • buf: 指定用于存储读取数据的缓冲区。
  • count: 指定需要读取的字节数。
  • 返回值: 如果读取成功将返回读取到的字节数,实际读取到的字节数可能会小于 count 参数指定的字节 数,也有可能会为 0,譬如进行读操作时,当前文件位置偏移量已经到了文件末尾。 实际读取到的字节数少 于要求读取的字节数,譬如在到达文件末尾之前有 30 个字节数据,而要求读取 100 个字节,则 read 读取成 功只能返回 30;而下一次再调用 read 读,它将返回 0(文件末尾) 。

4.close 关闭文件

//函数原型
#include <unistd.h>
int close(int fd);

函数参数和返回值含义如下:

  • fd: 文件描述符,需要关闭的文件所对应的文件描述符
  • 返回值: 如果成功返回 0,如果失败则返回-1

注:除了使用 close 函数显式关闭文件之外,在 Linux 系统中,当一个进程终止时,内核会自动关闭它打开 的所有文件,也就是说在我们的程序中打开了文件, 如果程序终止退出时没有关闭打开的文件,那么内核会 自动将程序中打开的文件关闭。 很多程序都利用了这一功能而不显式地用 close 关闭打开的文件。

demo

// 1. 将文件 a.txt 中的内容读出来,并显示到屏幕上
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>
#include <stdio.h>
int main()
{
    int fd = open("a.txt", O_RDWR);
    char buf[100];
    int n;
    while (1)
    {
        bzero(buf, 100);
        n = read(fd, buf, 100); // 每次最多读取100个字节
        if (n == 0) // 读完退出
            break;
        printf("%s", buf);
    }
    printf("\n");
    close(fd);
}
// 2. 将键盘输入的内容,写入文件 a.txt
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <strings.h>
#include <stdio.h>
#include <string.h>
int main()
{
    int fd = open("a.txt", O_RDWR);
    char buf[10];
    bzero(buf, 10);
    // 从键盘输入数据
    fgets(buf, 10, stdin);
    // 将输入的数据写入文件
    write(fd, buf, strlen(buf));
    close(fd);
}

5.lseek 位置偏移量

  • 文件的读写位置可以通过lseek任意调整
//函数原型
#include <sys/types.h> 
#include <unistd.h> off_t lseek(int fd, off_t offset, int whence);

函数参数和返回值含义如下:

  • fd: 文件描述符
  • offset: 偏移量,以字节为单位
  • whence: 用于定义参数 offset 偏移量对应的参考值, 该参数为下列其中一种(宏定义) :
    • SEEK_SET:读写偏移量将指向 offset 字节位置处(从文件头部开始算)
    • SEEK_CUR:读写偏移量将指向当前位置偏移量 + offset 字节位置处, offset 可以为正、也可以为 负,如果是正数表示往后偏移,如果是负数则表示往前偏移
    • SEEK_END:读写偏移量将指向文件末尾 + offset 字节位置处,同样 offset 可以为正、也可以为负
  • 返回值:成功将返回从文件头部开始算起的位置偏移量(字节为单位), 也就是当前的读写位置; 发生 错误将返回-1
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <strings.h>

int main(void)
{
    // 假设文件 a.txt 只有一行
    // 1234567890abcde 
    int fd = open("a.txt", O_RDWR);

    // 读取前面10个阿拉伯数字:
    char buf[10];
    read(fd, buf, 10);
    printf("%s\n", buf);
    bzero(buf, 10);

    // 将文件位置调整到'c'
    lseek(fd, 2, SEEK_CUR);
    read(fd, buf, 1);
    printf("%s\n", buf);
    bzero(buf, 10);
    
    // 将文件位置调整到'1'
    lseek(fd, 0, SEEK_SET);
    read(fd, buf, 1);
    printf("%s\n", buf);
    bzero(buf, 10);

    // 将文件位置调整到'a'
    lseek(fd, -5, SEEK_END);
    read(fd, buf, 1);
    printf("%s\n", buf);
    bzero(buf, 10);
}

感谢阅读我的博客,如果你喜欢的话,不妨点赞收藏关注一波!

作者:小海编程心语录-CSDN博客

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值