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

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

相关推荐
cominglately2 小时前
centos单机部署seata
linux·运维·centos
魏 无羡2 小时前
linux CentOS系统上卸载docker
linux·kubernetes·centos
CircleMouse2 小时前
Centos7, 使用yum工具,出现 Could not resolve host: mirrorlist.centos.org
linux·运维·服务器·centos
木子Linux3 小时前
【Linux打怪升级记 | 问题01】安装Linux系统忘记设置时区怎么办?3个方法教你回到东八区
linux·运维·服务器·centos·云计算
mit6.8243 小时前
Ubuntu 系统下性能剖析工具: perf
linux·运维·ubuntu
鹏大师运维3 小时前
聊聊开源的虚拟化平台--PVE
linux·开源·虚拟化·虚拟机·pve·存储·nfs
watermelonoops3 小时前
Windows安装Ubuntu,Deepin三系统启动问题(XXX has invalid signature 您需要先加载内核)
linux·运维·ubuntu·deepin
滴水之功4 小时前
VMware OpenWrt怎么桥接模式联网
linux·openwrt
ldinvicible4 小时前
How to run Flutter on an Embedded Device
linux
YRr YRr5 小时前
解决Ubuntu 20.04上编译OpenCV 3.2时遇到的stdlib.h缺失错误
linux·opencv·ubuntu