Linux 文件 I/O

1.Linux 应用编程中最基础的知识,即文件 I/O(Input、 Outout) , 文件 I/O 指的是对文件的输入/输出操作,说白了就是对文件的读写操作

Linux 下一切皆文件,文件作为 Linux 系统设计思想的核心理念,在 Linux 系统下显得尤为重要,所以对文件的 I/O 操作既是基础也是最重要的部分。

2.一个通用的 IO 模型通常包括打开文件、读写文件、关闭文件这些基本操作, 主要涉及到 4 个函数: open()、 read()、 write()以及 close()

一个简单地文件 IO 示例
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(void)
{
    char buff[1024];
    int fd1, fd2;
    int ret;
    
    /* 打开源文件 src_file(只读方式) */
    fd1 = open("./src_file", O_RDONLY);
    if (-1 == fd1)
        return fd1;
    
    /* 打开目标文件 dest_file(只写方式) */
    fd2 = open("./dest_file", O_WRONLY);
    if (-1 == fd2) {
        ret = fd2;
        goto out1;
    }
    
    /* 读取源文件 1KB 数据到 buff 中 */
    ret = read(fd1, buff, sizeof(buff));
    if (-1 == ret)
        goto out2;
    
    /* 将 buff 中的数据写入目标文件 */
    ret = write(fd2, buff, sizeof(buff));
    if (-1 == ret)
        goto out2;
        
    ret = 0;
    
out2:
    /* 关闭目标文件 */
    close(fd2);
    
out1:
    /* 关闭源文件 */
    close(fd1);
    
    return ret;
}

3.文件描述符

调用 open 函数会有一个返回值, 譬如示例代码 2.1.1 中的 fd1 和 fd2, 这是一个 int 类型的数据,在 open函数执行成功的情况下, 会返回一个非负整数, 该返回值就是一个文件描述符(file descriptor) , 这说明文件描述符是一个非负整数; 对于 Linux 内核而言,所有打开的文件都会通过文件描述符进行索引。

当调用 open 函数打开一个现有文件或创建一个新文件时,内核会向进程返回一个文件描述符, 用于指代被打开的文件,所有执行 IO 操作的系统调用都是通过文件描述符来索引到对应的文件,譬如示例代码

2.1.1 中,当调用 read/write 函数进行文件读写时,会将文件描述符传送给 read/write 函数, 所以在代码中,fb1 就是源文件 src_file 被打开时所对应的文件描述符, 而 fd2 则是目标文件 dest_file 被打开时所对应的文件描述符。

文件描述符是一种有限资源, 文件描述符是从 0 开始分配的,以此类推。

调用 open 函数打开文件的时候,分配的文件描述符一般都是从 3 开始,但是 0、 1、 2 这三个文件描述符已经默认被系统占用了,分别分配给了系统标准输入(0)、 标准输出(1)以及标准错误(2)。

3.1标准输入一般对应的是键盘,可以理解为 0 便是打开键盘对应的设备文件时所得到的文件描述符;标准输出一般指的是 LCD 显示器,可以理解为 1 便是打开 LCD 设备对应的设备文件时所得到的文件描符;而标准错误一般指的也是 LCD 显示器。

4.open 打开文件

man 2 open #查看 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: 字符串类型,用于标识需要打开或创建的文件,可以包含路径(绝对路径或相对路径) 信息,譬如: "./src_file"(当前目录下的 src_file 文件)。

flags: 调用 open 函数时需要提供的标志, 包括文件访问模式标志以及其它文件相关标志,这些标志使用宏定义进行描述,都是常量, open 函数提供了非常多的标志,我们传入 flags 参数时既可以单独使用某一个标志,也可以通过位或运算(|) 将多个标志进行组合。

O_RDONLY 以只读方式打开文件
O_WRONLY 以只写方式打开文件
O_RDWR   以可读可写方式打开文件

mode: 此参数用于指定新建文件的访问权限,只有当 flags 参数中包含 O_CREAT 或 O_TMPFILE 标志时才有效(O_TMPFILE 标志用于创建一个临时文件)。

如果需要修改文件权限,可通过 chmod 命令对文件权限进行修改;

使用"ls -l"命令来查看到文件所对应的权限。

open 函数使用示例

(1)使用 open 函数打开一个已经存在的文件(例如当前目录下的 app.c 文件),使用只读方式打开

int fd = open("./app.c", O_RDONLY)
if (-1 == fd)
    return fd;

(2)使用 open 函数打开一个已经存在的文件(例如当前目录下的 app.c 文件),使用可读可写方式打开:

int fd = open("./app.c", O_RDWR)
if (-1 == fd)
    return fd;

(3)使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello) , 使用可读可写方式,如果该文件是一个符号链接文件,则不对其进行解引用,直接返回错误:

int fd = open("/home/dengtao/hello", O_RDWR | O_NOFOLLOW);
if (-1 == fd)
    return fd;

(4)使用 open 函数打开一个指定的文件(譬如/home/dengtao/hello),如果该文件不存在则创建该文件,创建该文件时,将文件权限设置如下:

文件所属者拥有读、写、执行权限;

同组用户与其他用户只有读权限。

使用可读可写方式打开:

int fd = open("/home/dengtao/hello", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH);
if (-1 == fd)
    return fd;

5.write 写文件 --- 调用 write 函数可向打开的文件写入数据。

man 2 write

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

fd: 文件描述符。需要将进行写操作的文件所对应的文件描述符传递给 write 函数。

buf: 指定写入数据对应的缓冲区。

count: 指定写入的字节数。

返回值: 如果成功将返回写入的字节数(0 表示未写入任何字节),如果此数字小于 count 参数,这不

是错误,譬如磁盘空间已满,可能会发生这种情况;如果写入出错,则返回-1

6.read 读文件 --- 可从打开的文件中读取数据

man 2 read

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

fd: 文件描述符。与 write 函数的 fd 参数意义相同。

buf: 指定用于存储读取数据的缓冲区。

count: 指定需要读取的字节数。

返回值: 如果读取成功将返回读取到的字节数。

7.close 关闭文件 --- 关闭一个已经打开的文件

man 2 close

#include <unistd.h>
int close(int fd);

fd: 文件描述符,需要关闭的文件所对应的文件描述符。

返回值: 如果成功返回 0,如果失败则返回-1。

注:在我们的程序中打开了文件, 如果程序终止退出时没有关闭打开的文件,那么内核会自动将程序中打开的文件关闭。

7.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值