Linux:基础IO(一)

我们之前一直在学习进程,但是在最开始的时候,我们讲过linux下一切皆文件,但是什么才是真正的文件呢,我们使用mkdir,cd,都是在创造,使用文件,但是只停留在表面上,今天我们将学习一下什么才是真正的文件

1.狭义理解

⽂件在磁盘⾥
磁盘是永久性存储介质,因此⽂件在磁盘上的存储是永久性的
磁盘是外设(即是输出设备也是输⼊设备)
磁盘上的⽂件 本质是对⽂件的所有操作,都是对外设的输⼊和输出 简称 IO
所以以后只要是不做说明的文件,我们都默认为狭义文件

2.⼴义理解

Linux 下⼀切皆⽂件(键盘、显⽰器、⽹卡、磁盘...... 这些都是抽象化的过程)(后⾯会讲如何去
理解)

3.⽂件操作的归类认知

对于 0KB 的空⽂件是占⽤磁盘空间的(文件 = 属性 + 内容(空),但是属性不空)
⽂件是⽂件属性(元数据)和⽂件内容的集合(⽂件 = 属性(元数据)+ 内容)
所有的⽂件操作本质是⽂件内容操作和⽂件属性操作

4.系统⻆度

对⽂件的操作本质是进程对⽂件的操作
磁盘的管理者是操作系统
⽂件的读写本质不是通过 C 语⾔ / C++ 的库函数来操作的(这些库函数只是为⽤⼾提供⽅便),⽽真正对文件操作是通过⽂件相关的系统调⽤接⼝来实现的

5.回顾C⽂件接⼝

我们在c语言之中,最常用的就是fopen与fclose打开关闭文件
下面我们回顾一下这两个接口

写⽂件

hello.c:

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    FILE* fp = fopen("log.txt", "w");
    if (fp == NULL)
    {
        perror("fopen");
        return 1;
    }
    for (int i = 0; i < 10; i++)
    {
        char buffer[1024];
        const char* message = "Hello Linux";
        snprintf(buffer, sizeof(buffer), "%s : %d\n", message, i);
        fwrite(buffer, strlen(buffer), 1, fp);
    }
    fclose(fp);
    return 0;
}

下面是运行结果,创造了log.txt并且里面的内容是我们想看到的内容

读⽂件

读文件顾名思义就是把文件内容读取出来,我们要是读出来并且打印出来,不就是cat命令了吗

所以我们下面实现一个自己的cat命令

mycat:

cpp 复制代码
#include <stdio.h>

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        printf("Usage : ./mycat filename\n");
        return 1;
    }
    FILE* fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        perror("fopen");
        return 1;
    }
    while (1)
    {
        char message[1024];
        int n = fread(message, 1, sizeof(message) - 1, fp);
        if (n > 0)
        {
            message[n] = '\0';
            printf("%s", message);
        }
        if (feof(fp))
        {
            break;
        }
    }
    fclose(fp);
    return 0;
}

运行结果符合预期

6.再探写文件

我们修改一下hello.c代码

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    FILE* fp = fopen("log.txt", "w");
    if (fp == NULL)
    {
        perror("fopen");
        return 1;
    }

    //for (int i = 0; i < 10; i++)
    //{
    //    char buffer[1024];
    //    const char* message = "Hello Linux";
    //    snprintf(buffer, sizeof(buffer), "%s : %d\n", message, i);
    //    fwrite(buffer, strlen(buffer), 1, fp);
    //}
    fclose(fp);
    return 0;
}

发现直接将log.txt清除了!!

所以我们知道了,fopen(w)的时候,是先将文件清空,然后再写入内容,所以我们得使用"a"追加内容

我们再来看看echo message > filename这个命令

发现和fopen(w)的现象一样,都是先清除再写入,所以我们可以写出一个echo > ,即用fopen(w)打开,然后写入内容

那么echo message >> filename

发现是追加,即和fopen(a)的现象一样,都是追加写入,所以我们可以写出一个echo > >,即用fopen(a)打开,然后写入内容

7.stdin & stdout & stderr

C默认会打开三个输⼊输出流,分别是stdin, stdout, stderr
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,⽂件指针

cpp 复制代码
#include <stdio.h>
extern FILE *stdin;
extern FILE *stdout;
extern FILE *stderr;

这也间接说明我们操作的都是文件,即一切皆文件

好啦,这就是文件IO的简单概括与c语言常见接口的简单回顾,接下来的博客才是文件IO的重头戏哦~~下偏见~~

相关推荐
chlk12316 小时前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑16 小时前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件17 小时前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
碳基沙盒17 小时前
OpenClaw 多 Agent 配置实战指南
运维
深紫色的三北六号1 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash1 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI2 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
Sinclair3 天前
简单几步,安卓手机秒变服务器,安装 CMS 程序
android·服务器
木心月转码ing3 天前
WSL+Cpp开发环境配置
linux