【Linux后端服务器开发】基础IO与文件系统

news2024/9/23 19:28:28

目录

一、基础IO

1. C语言文件读写

2. 标志位传参

3. C语言与系统调用关系

二、文件系统

1. 文件描述符

2. 输入输出重定向


一、基础IO

文件调用

  • 库函数接口: fopen、fclose、fwrite、fread、fseek
  • 系统调用接口:open、close、write、read、lseek

1. C语言文件读写

  • r/w/a :读/写/追加
  • 若打开的文件不存在,“r”报错,“w/a”创建
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main() 
{
    //FILE* pf = fopen("test.txt", "w");
    //FILE* pf = fopen("test.txt", "a");
    FILE* pf = fopen("test.txt", "r");
    if (pf == NULL) 
    {
        perror("fopen");
        exit(errno);
    }

    //w
    // int cnt = 5;
    // while (cnt--) 
    //     fprintf(pf, "%s\n", "hello world -- write");


    //a
    // int cnt = 5;
    // while (cnt--) 
    //     fprintf(pf, "%s\n", "append");


    //r
    char buffer[64];
    while (fgets(buffer, sizeof(buffer) - 1, pf)) 
    {
        buffer[strlen(buffer) - 1] = 0;
        printf("%s\n", buffer);
    }

    return 0;       
}

2. 标志位传参

#include <stdio.h>

#define ONE (1 << 1)
#define TWO (1 << 2)
#define THREE (1 << 3)
#define FOUR (1 << 4)

void Show(int flag) 
{
    if (flag & ONE) 
        printf("one\n");
    if (flag & TWO) 
        printf("two\n");
    if (flag & THREE) 
        printf("three\n");
    if (flag & FOUR) 
        printf("four\n");
}

void ShowTest() 
{
    Show(ONE);
    printf("-----------\n");
    Show(TWO);
    printf("-----------\n");
    Show(TWO | THREE);
    printf("-----------\n");
    Show(TWO | THREE | FOUR);
}

int main() 
{
    ShowTest();
    return 0;       
}

 

3. C语言与系统调用关系

  • "w" ----> O_WRONLY | O_CREAT | O_TRUNC
  • "a" ----> O_WRONLY | O_CREAT | O_APPEND
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main() 
{
    umask(0);   //只修改当前进程的umask
    //int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    //int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
    int fd = open("test.txt", O_RDONLY);
    if (fd < 0) 
    {
        perror("open");
        return 1;
    }

    //写/追加
    // int cnt = 5;
    // char outBuffer[64] = {0};
    // while (cnt--) 
    // {
    //     sprintf(outBuffer, "%s: %d\n", "hello --- a", cnt);
    //     write(fd, outBuffer, strlen(outBuffer));
    // }

    //读
    char buffer[1024];
    ssize_t num = read(fd, buffer, sizeof(buffer) -  1);
    if (num > 0) 
    {
        buffer[num] = 0;
    }
    printf("%s", buffer);

    return 0;       
}

二、文件系统

在Linux中,一切皆文件,不仅普通的文件和目录,块设备、管道、socket等等,都是由文件系统管理的。在Linux中的文件系统会给每个文件分配两个数据结构:索引节点(index node)和目录项(directory entry),它们都主要是被用来记录文件的元信息和目录层次结构。

  • 索引节点,inode,用来记录文件的元信息,比如inode编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等。索引节点是文件的唯一标识,它们之间一一对应,也同样都是被存储在硬盘当中,索引节点也是会占用磁盘的存储空间的。
  • 目录项,dentry,用来记录文件的名字,索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但是它与索引节点不相同的是,目录项是由内核维护的一个数据结构,不是存放咋磁盘中,而是缓存在内存里面。目录项包括文件名和inode节点号。

1. 文件描述符

文件描述符(file descripter)FD:Linux内容默认情况下一个进程只能打开1024个文件,内核为了管理进程,当一个进程打开了哪些文件,内核就会维护一个表,这个表就会记录这个进程打开了哪些文件,然后给每个文件进行编号,这个编号就叫文件描述符(句柄),默认文件描述符的范围为0-1023。
 

三个标准输入输出流:

  • stdin:标准输入,0
  • stdout:标准输出,1
  • stderr:标准错误,2

FILE ----> 结构体

文件描述符表:struct file* fd_array[]

文件分配规则:寻找最小且没被占用的下标

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define TEST_FILE(number) "test"#number

int main() 
{
    umask(0);
    printf("stdin   --->   fd : %d\n", stdin->_fileno);     //0
    printf("stdout  --->   fd : %d\n", stdout->_fileno);    //1
    printf("stderr  --->   fd : %d\n", stderr->_fileno);    //2

    //close(0);
    //close(2);
    close(1);   //关闭文件描述符对应下标的文件
                //关闭文件描述符表的 1 后, fd0 会被分配到 1 的位置,也就是原本stdout的位置
                //而原本输出到stdout的数据,会写入 fd0 中

    int fd0 = open(TEST_FILE(0), O_WRONLY | O_CREAT | O_APPEND, 0666);
    int fd1 = open(TEST_FILE(1), O_WRONLY | O_CREAT | O_APPEND, 0666);
    int fd2 = open(TEST_FILE(2), O_WRONLY | O_CREAT | O_APPEND, 0666);
    int fd3 = open(TEST_FILE(3), O_WRONLY | O_CREAT | O_APPEND, 0666);

    printf("fd : %d\n", fd0);
    printf("fd : %d\n", fd1);
    printf("fd : %d\n", fd2);
    printf("fd : %d\n", fd3);       //fd分配规则,寻找最小的且没被占用的下标
    fprintf(stdout, "fd : %d\n", fd3);  //打印到 f0 对应的文件
    fflush(stdout);

    close(fd0);
    close(fd1);
    close(fd2);
    close(fd3);

    return 0;       
}

2. 输入输出重定向

int dup2(int old_fd, int new_fd)

重定向:将新的文件文件描述符充当老的文件描述符的一份拷贝(old_fd内容 拷贝到 new_fd内容)

上层的fd不变,在内核中更改fd对应的struct file*地址

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

int main() 
{
    umask(0);
    //int fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666);
    //int fd = open("test.txt", O_WRONLY | O_CREAT | O_APPEND, 0666);
    int fd = open("test.txt", O_RDONLY);
    if (fd < 0) 
    {
        perror("open");
        return 1;
    }

    //输出重定向
    // dup2(fd, 1);
    // printf("open fd: %d\n", fd);
    // fprintf(stdout, "open fd: %d\n", fd);
    // const char* msg = "hello world\n";
    // write(1, msg, strlen(msg));
    // fflush(stdout);

    //输入重定向
    dup2(fd, 0);
    char line[1024];
    while (1) 
    {
        printf("> ");
        if (fgets(line, sizeof(line) - 1, stdin) == NULL) 
            break;
        printf("%s", line);
    }

    close(fd);
    return 0;       
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

利用 kube-vip 实现 K3s 高可用部署

作者简介 王海龙&#xff0c;Rancher 中国社区技术经理&#xff0c;Linux Foundation APAC Evangelist&#xff0c;负责 Rancher 中国技术社区的维护和运营。拥有 9 年的云计算领域经验&#xff0c;经历了 OpenStack 到 Kubernetes 的技术变革&#xff0c;无论底层操作系统 Lin…

腾讯音乐娱乐集团2023校园招聘技术类岗位编程题合集

字符串操作 题解&#xff1a;先变为没出现过的字符&#xff0c;然后在正常的变换 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** 返回满足题意的最小操作数* param str string字符串 给定…

Python绘制直方图

文章目录 初步参数绘图类型多组数据直方图对比 初步 对于大量样本来说&#xff0c;如果想快速获知其分布特征&#xff0c;最方便的可视化方案就是直方图&#xff0c;即统计落入不同区间中的样本个数。 以正态分布为例 import numpy as np import matplotlib.pyplot as pltxs…

用c++实现大小端序互转(字符串方法)

今天在逆一个RC4加密算法&#xff0c;忘了IDA如何自动将大小端序互转的按键&#xff0c;索性自己写了一个&#xff0c;因为是用字符串方法&#xff0c;所以理论上长度是管够的 #include <iostream> #include <string> using namespace std; int main() {string m_…

macOS 14 Sonoma Beta 测试版体验,不影响主力系统

今年的 WWDC 上 Apple 依旧保持往年的发布节奏&#xff0c;公布了今年的 macOS 新版本&#xff1a;macOS Sonoma&#xff0c;不过和以往有些不太一样的是&#xff0c;这一次 Apple 将测试版系统直接下发给了普通开发者账户&#xff0c;对于一般用户简单注册就可以直接获得 macO…

Windows VScode如何配置与使用git?

当我们在VScode中编写代码后&#xff0c;需要提交到git仓库时&#xff0c;但是我们又不想切换到git的命令行窗口&#xff0c;我们可以在VScode中配置git&#xff0c;然后就可以很方便快捷的把代码提交到仓库中。 1. 官网下载安装Git命令行工具 根据自己的电脑系统&#xff0c…

分布式ELK日志文件分析系统(曾经沧海难为水,除却巫山不是云)

文章目录 一、ELK 概述1. 为什么要使用 ELK2. 完整日志系统基本特征3. ELK 简介3.1 ElasticSearch&#xff08;ES&#xff09;3.2 Kiabana3.3 Logstash3.4 其它组件Filebeat缓存/消息队列Fluentd 4. ELK 的工作原理5. Linux 系统内核日志消息的优先级别 二、 部署 ELK 集群服务…

基于matlab检测交通视频中的汽车(附源码)

一、前言 此示例说明如何使用工具箱可视化和分析视频或图像序列。此示例来检测交通视频中的浅色汽车。请注意&#xff0c;VideoReader 的有些功能特定于平台&#xff0c;可能无法在某些平台上读取提供的 Motion JPEG2000 视频。 二、步骤 步骤 1&#xff1a;使用 VideoReade…

用IDEA写第一个Spring程序 HelloWorld

用IDEA写第一个Spring程序 HelloWorld 环境 Orcal JDK&#xff1a;1.8.0_341 maven&#xff1a;3.9.3 Spring&#xff1a;5.3.10 IDEA&#xff1a;2023.1.2 1. 安装JDK和IDEA 2. 安装maven并配置环境变量、换源 3. IDEA中maven属性配置&#xff0c;主要是版本和settings文件及…

React 新版官方文档 (一) useReducer 用法详解

useReducer useReducer 是一个可以让你向组件中添加 reducer 的 Hook const [state, dispatch] useReducer(reducer, initialArg, init?)基本用法 const reducer (state, action) > { ... } const MyComponent () > {const [state, dispatch] useReducer(reducer…

820. 递归求斐波那契数列

链接&#xff1a; 原题 题目&#xff1a; 请使用递归的方式求斐波那契数列的第 nn 项&#xff0c;下标从1开始。 斐波那契数列&#xff1a;1,1,2,3,5…1,1,2,3,5…&#xff0c;这个数列从第 33 项开始&#xff0c;每一项都等于前两项之和 输入格式 共一行&#xff0c;包含整数 …

npm 包和模块简介

目录 1、关于公共npm注册表 2、关于包和模块 2.1、关于包 2.2、关于包格式 2.3、npm包git URL格式 2.4、关于模块 3、关于范围 3.1、作用域和包的可见性 4、关于公共软件包 5、关于私有包 6、npm包范围、访问级别和可见性 1、关于公共npm注册表 公共npm注册表是Jav…

学习单片机的三个步骤:基础知识、编程语言和实践项目

当然&#xff01;学习单片机的过程可以分为以下三个步骤&#xff1a; 学习基础知识&#xff1a;在开始学习单片机之前&#xff0c;首先需要掌握一些基础知识。了解数字电子学和模拟电子学的基本原理是很重要的&#xff0c;包括数字和模拟信号、逻辑门、计数器、寄存器等。还需…

K8S应用安全检测(调用分析 容器健康 审计日志)

应用安全检测 1 应用安全检测1.1 调用分析1.1.1 sysdig基础1.1.2 命令实践 1.2 容器监控1.2.1 CAdvisor1.2.2 Falco基础1.2.3 Falco实践1.2.4 进阶实践1.2.5 可视化实践 1.3 审计日志1.3.1 日志解读1.3.2 审计日志 1 应用安全检测 1.1 调用分析 1.1.1 sysdig基础 学习目标 …

第六章 mac上用的软件

1、brew.sh/index_zh-cn 2、网易有道词典 3、SizeUP 4、 5、chrome浏览器插件 6、快捷键

最近,智慧公厕空位引导系统非常受园区、写字楼、工厂、大型商场青睐,大家都在争着上!

随着城市化进程的不断推进&#xff0c;楼宇智慧公厕管理系统的应用已经成为城市管理的重要一环。通过智能化的监控和管理&#xff0c;公厕的卫生状况得到了有效控制&#xff0c;为市民提供了更好的公厕服务。一、楼宇智慧公厕系统案例展示楼宇智慧公厕系统是一种基于智能科技的…

基础算法-差分矩阵

&#xff08;一&#xff09;课堂笔记 &#xff08;二&#xff09;思路详解 如果扩展到二维&#xff0c;我们需要让二维数组被选中的子矩阵中的每个元素的值加上c,是否也可以达到O(1)的时间复杂度。答案是可以的&#xff0c;考虑二维差分。 a[][]数组是b[][]数组的前缀和数组&a…

less预处理语言的运用之-变量拼接那点事

less语法的技巧总结&#xff0c;很基础&#xff0c;熟练掌握后能提高我们在大型项目中的开发效率 a:0.5; showdaw-px:100; mkcolor1:#6ec5ff; num:1; .outer{//拼接的字符串在变量后面&#xff0c;需要在冒号后面加~width:~"{showdaw-px}px";//拼接的字符串在冒号后…

Vue脚手架使用 【实战篇】

一、一个组件引用另一个组件&#x1f349; (1) 引入被引用的组件&#x1f95d; 自己创建的组件 lzq.vue 组件必须创建在components文件夹下 将自己创建的组件导入到主页面中 (2)声明该组件&#x1f95d; 本人理解&#xff1a; 声明组件可以理解为声明一个变量一样 (3)使用组…

【sql注入-报错注入2】GTID_SUBTRACT()函数 报错注入

目录 GTID_SUBTRACT()报错注入 一、语法介绍&#xff1a; 二、报错原因 网络安全小圈子 &#xff08;***注&#xff1a;注意看版本要求&#xff09; GTID_SUBTRACT()报错注入 一、语法介绍&#xff1a; 版本&#xff1a; MySQL >5.6 GTID_SUBTRACT()函数是MySQL中的一…