<Linux> 基础IO

文章目录

基础IO

文件描述符

系统底层提供打开文件(open),读(read),写(write),关闭文件(close)的系统调用,如果想详细了解可以复制以下命令仔细阅读使用方法,这里不做赘述。

打开文件

shell 复制代码
man 2 open

shell 复制代码
man 2 read

shell 复制代码
man 2 write

关闭文件

shell 复制代码
man close

文件描述符fd,是file descriptor的简写,数据类型是int

这里我们新建4个文件

然后打开这4个文件,用4个文件描述符去接收返回值

代码如下

c 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
    int fd1 = open("test1.txt", O_RDONLY);
    int fd2 = open("test2.txt", O_RDONLY);
    int fd3 = open("test3.txt", O_RDONLY);
    int fd4 = open("test4.txt", O_RDONLY);

    if (-1 == fd1)
    {
        perror("open file:");
        _exit(1);
    }
    if (-1 == fd2)
    {
        perror("open file:");
        _exit(1);
    }
    if (-1 == fd3)
    {
        perror("open file:");
        _exit(1);
    }
    if (-1 == fd4)
    {
        perror("open file:");
        _exit(1);
    }

    printf("%d\n", fd1);
    printf("%d\n", fd2);
    printf("%d\n", fd3);
    printf("%d\n", fd4);

    return 0;
}

运行结果如下:

看起来是按顺序递增,这是什么意思?难道跟数组下标有关?

open打开文件失败会返回-1,成功则会返回一个非负整数,可是这里为什么是从3开始递增?0,1,2呢?

0,1,2是预留给标准输入,标准输出,标准错误的,在进程创建时就已经被操作系统打开。

在进程打开文件时,进程内部会有一个数组指针,指向该进程的文件指针数组,而默认打开的标准输入,标准输出,标准错误就是该数组的0,1,2下标,在我们新打开文件时,这时就会从头开始扫描该数组,找到第一个为空的,存放内存中该文件地址,文件描述符就是该数组下标。

文件描述符本质:数组下标

原理图如下

重定向

重定向将输入或输出从标准位置改变到其他位置。

输出重定向

将原本输出到显示器改为输出到文件,打印文件内容即可查看信息

输入重定向

将原本从键盘读取输入改为从文件中读取输入,这就是输入重定向

重定向本质

输入重定向本质,将标准输入改为别的文件,就可以从该文件中读取输入,而不是从键盘读取输入。

输出重定向本质,将标准输出改为别的文件,就可以输出到该文件,而不是输出到显示器。

输入重定向验证

c 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
    close(0);
    int fd = open("input.txt", O_RDONLY);
    if (-1 == fd)
    {
        perror("open file:");
        _exit(1);
    }

    char buffer[64];
    memset(buffer, '\0', sizeof buffer);
    read(0, buffer, sizeof buffer);

    write(1, buffer, strlen(buffer));
    close(fd);
    return 0;
}

因为标准输入认准的就是0号下标,所以我们就让input.txt文件描述符成为0,原本从键盘读取输入变为从input.txt中读取数据,这就是输入重定向本质。

结果如下

输出重定向验证

c 复制代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
    close(1);
    int fd = open("output.txt", O_WRONLY | O_APPEND);
    if (-1 == fd)
    {
        perror("open file:");
        _exit(1);
    }

    char buffer[64];

    fgets(buffer, sizeof buffer, stdin);
    write(1, buffer, strlen(buffer));
    close(fd);
    return 0;
}

运行起来之后,命令行会等待输入,我们输入字符串后,结果并没有显示在显示器上,打印output.txt文件后可以看到输入的字符串。

重定向系统调用

上面的代码只是为了验证重定向底层原理,如果想让实现重定向可以使用系统调用,可以查看下使用手册

shell 复制代码
man dup

这里使用dup2

c 复制代码
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main() {
    // 打开文件 "output.txt" 并获取文件描述符
    int file_fd = open("output.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (file_fd < 0) {
        perror("open");
        return 1;
    }

    // 使用 dup2 将标准输出 (file descriptor 1) 重定向到文件描述符 file_fd
    if (dup2(file_fd, STDOUT_FILENO) < 0) {
        perror("dup2");
        close(file_fd);
        return 1;
    }

    printf("hello linux\n");


    close(file_fd);

    return 0;
}

原本打印到标准输出的内容就会被重定向到显示器

相关推荐
Komorebi.py17 分钟前
【Linux】-学习笔记05
linux·笔记·学习
Mr_Xuhhh22 分钟前
重生之我在学环境变量
linux·运维·服务器·前端·chrome·算法
内核程序员kevin3 小时前
TCP Listen 队列详解与优化指南
linux·网络·tcp/ip
朝九晚五ฺ8 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
自由的dream8 小时前
Linux的桌面
linux
xiaozhiwise8 小时前
Makefile 之 自动化变量
linux
意疏11 小时前
【Linux 篇】Docker 的容器之海与镜像之岛:于 Linux 系统内探索容器化的奇妙航行
linux·docker
BLEACH-heiqiyihu11 小时前
RedHat7—Linux中kickstart自动安装脚本制作
linux·运维·服务器
一只爱撸猫的程序猿11 小时前
一个简单的Linux 服务器性能优化案例
linux·mysql·nginx