Linux —— 基础I/O(一)

news2024/11/24 20:27:17

目录

一,背景介绍

二,系统接口函数

open 打开或创建文件

close 关闭文件

read 读取文件

write 写入文件

三,文件描述符

结构体指针files

结构体指针files指向的表files_struct

文件结构体


一,背景介绍

        狭义的文件存放在磁盘上,广义上在Linux下一切皆文件;磁盘上的文件一般为永久存储的外设,本质上对文件的操作,即为对外设的输入和输出(简称I/O);空文件并不是不占磁盘文件,只是没有内容,文件=属性(元数据)+内容;对文件的内容操作,如fread、fwrite、fgets、fgetc,fputc,fputs等;对文件的属性操作,如fseek、ftell、rewind等;

        从系统角度,对文件的操作,其实就是进程对文件的操作;是通过系统调用接口,来实现操作的;

当前路径,每个进程都有一个内置属性cwd(即当前工作目录);

[wz@192 ~]$ ll /proc/29286
total 0
dr-xr-xr-x. 2 wz wz 0 8月   7 19:11 attr
-rw-r--r--. 1 wz wz 0 8月   7 19:11 autogroup
-r--------. 1 wz wz 0 8月   7 19:11 auxv
-r--r--r--. 1 wz wz 0 8月   7 19:11 cgroup
--w-------. 1 wz wz 0 8月   7 19:11 clear_refs
-r--r--r--. 1 wz wz 0 8月   7 19:10 cmdline
-rw-r--r--. 1 wz wz 0 8月   7 19:11 comm
-rw-r--r--. 1 wz wz 0 8月   7 19:11 coredump_filter
-r--r--r--. 1 wz wz 0 8月   7 19:11 cpuset
lrwxrwxrwx. 1 wz wz 0 8月   7 19:11 cwd -> /home/wz/Desktop
-r--------. 1 wz wz 0 8月   7 19:11 environ
lrwxrwxrwx. 1 wz wz 0 8月   7 19:11 exe -> /home/wz/Desktop/target
dr-x------. 2 wz wz 0 8月   7 19:10 fd
...

 在任何C程序,都会默认打开三个文件(硬件):

  • 标准输入,stdin,键盘文件;
  • 标准输出,stdout,显示器文件;
  • 标准错误,stderr,显示器文件;

注,所有外设硬件,本质上即对应read/write的核心操作;可通过C接口,直接对stdin/stdout/stderr进行读写操作;默认打开这三个文件,其他函数使用需求,如scanf、printf、perror等,另外fprintf、fscanf;其他语言也是如此,C++中是cin、cout、cerr;

二,系统接口函数

        open、close、read、write;

open 打开或创建文件

close 关闭文件

read 读取文件

write 写入文件

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int fd = open("log.txt", O_WRONLY|O_CREAT, 0644);
    if(fd<0)
    {
        perror("open");
        return -1;
    }
    const char* msg = "hello world\n";
    write(fd, msg, strlen(msg));
    close(fd);
    return 0; 
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int fd = open("log.txt", O_RDONLY);
    if(fd<0)
    {
        perror("open");
        return -1;
    }
    char buffer[1024];
    ssize_t s = read(fd, buffer, sizeof(buffer)-1);
    if(s>0)
    {
        buffer[s] = '\0';
        printf("%s\n", buffer);
    }
    close(fd);
    return 0; 
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int fd = open("log.txt", O_WRONLY|O_APPEND);
    if(fd<0)
    {
        perror("open");
        return -1;
    }
    const char* msg = "hello world append\n";
    write(fd, msg, strlen(msg));
    close(fd);
    return 0; 
}

注:

  • O_WRONLY|O_CREAT 对应C语言 w ;
  • O_RDONLY 对应C语言 r ;
  • O_WRONLY|O_APPEND 对应C语言 a ;

标签flags,O_WRONLY、O_CREAT、O_RDONLY、O_APPEND都是宏;

/usr/include/asm-generic/fcntl.h

#define O_ACCMODE 00000003
#define O_RDONLY  00000000
#define O_WRONLY  00000001
#define O_RDWR    00000002
#ifndef O_CREAT
#define O_CREAT   00000100  /* not fcntl */
#endif
#ifndef O_EXCL
#define O_EXCL    00000200  /* not fcntl */
#endif
#ifndef O_NOCTTY
#define O_NOCTTY  00000400  /* not fcntl */
#endif
#ifndef O_TRUNC
#define O_TRUNC   00001000  /* not fcntl */
#endif
#ifndef O_APPEND                                                                 
#define O_APPEND  00002000
#endif

        编程语言使用自己的接口,封装系统接口,是因为需兼容自身语法特征,且系统调用使用成本较高,不具备可移植性;

三,文件描述符

        Linux进程默认会有三个已打开的文件描述符,即0(stdin键盘)、1(stdout显示器)、2(stderr显示器);系统接口函数的返回值即为文件描述符,是从0开始的小整数,实际上是数组的下标;新文件的文件描述符使用当前没被使用的最小下标;

#include <stdio.h>      
#include <sys/types.h>      
#include <sys/stat.h>      
#include <fcntl.h>      
#include <unistd.h>      
#include <string.h>   

int main()      
{      
    int fd1 = open("log1.txt", O_WRONLY|O_CREAT, 0644);      
    int fd2 = open("log2.txt", O_WRONLY|O_CREAT, 0644);      
    int fd3 = open("log3.txt", O_WRONLY|O_CREAT, 0644);      
    int fd4 = open("log4.txt", O_WRONLY|O_CREAT, 0644);      
      
    printf("fd1=%d\n",fd1);  
    close(fd1);    
    printf("fd2=%d\n",fd2);                                                          
    printf("fd3=%d\n",fd3);      
    printf("fd4=%d\n",fd4);      
    return 0;       
}   
//新建的文件会从3开始
[wz@192 Desktop]$ ./target 
fd1=3
fd2=4
fd3=5
fd4=6

结构体指针files

  • 进程task_struct包含一个结构体指针files;

结构体指针files指向的表files_struct

  • 该表包含一个结构体指针数组;
  • 该数组中元素指向打开的文件;

文件结构体

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

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

相关文章

爆肝整理,接口测试-Fiddler对Jmeter请求抓包(详细实战)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 使用Fiddler结合J…

编写html页面让谷歌浏览器不弹出“翻译此页”的问题

文章目录 1.问题2.解决总结 1.问题 2.解决 如下图&#xff0c;将html的lang由en改为zh-CN&#xff08;注意大小写&#xff09; 总结 将html的lang由en改为zh-CN

基于PyTorch的图像识别

前言 图像识别是计算机视觉领域的一个重要方向&#xff0c;具有广泛的应用场景&#xff0c;如医学影像诊断、智能驾驶、安防监控等。在本项目中&#xff0c;我们将使用PyTorch来开发一个基于卷积神经网络的图像识别模型&#xff0c;用来识别图像中的物体。下面是要识别的四种物…

Java作业2

1.递归求解汉诺塔问题 拿三个为例子 先从A设法拿走两个盘子到B上&#xff0c;再拿一个盘子到C上&#xff0c;再从B上挪走一个到A&#xff0c;再挪下面的到C上 如果有N个盘子&#xff0c;我们也一样的步骤&#xff0c;先设法拿N-1个盘子到B&#xff0c;再拿最底部的盘子到C&a…

【算法】逆波兰表达式

文章目录 定义求法代码思想&#xff1a; 定义 逆波兰表达式也称为“后缀表达式”&#xff0c;是将运算符写在操作数之后的运算式。 求法 *如&#xff1a;(ab)c-(ab)/e的转换过程&#xff1a; 先加上所有的括号。 (((ab)*c)-((ab)/e))将所有的运算符移到括号外面 (((ab) c)* …

Unity游戏源码分享-全民飞机大战源码unity2019

Unity游戏源码分享-全民飞机大战源码unity2019 项目地址&#xff1a;https://download.csdn.net/download/Highning0007/88204008

67 # 对象的处理

上一节学习了 form 数据的处理&#xff0c;这一节学习 Ajax 的方式提交数据 服务端的代码如下 const http require("http"); const url require("url"); const querystring require("querystring");let server http.createServer();server…

定时器

定时器 定时器是什么 定时器也是软件开发中的一个重要组件. 类似于一个 “闹钟”. 达到一个设定的时间之后, 就执行某个指定好的代码. 定时器是一种实际开发中非常常用的组件. 比如网络通信中, 如果对方 500ms 内没有返回数据, 则断开连接尝试重连. 比如一个 Map, 希望里面的…

elasticsearch简单入门语法

基本操作 创建不同的分词器 ik_smart&#xff1a; 极简分词 &#xff1b; ik_max_word: 最细力再度分词 基本的rest命令 methodurl地址描述PUTlocalhost:9200/索引名称/类型名称/文档id创建文档&#xff08;指定文档id&#xff09;POSTlocalhost:9200/索引名称/类型名称创建文…

Qt应用开发(基础篇)——堆栈窗口 QStackedWidget

一、前言 QStackedWidget继承于QFrame&#xff0c;QFrame继承于QWidget&#xff0c;是Qt常用的堆栈窗口部件。 框架类QFrame介绍 QStackedWidget堆栈窗口&#xff0c;根据下标切换&#xff0c;一次显示一个小部件&#xff0c;常用于应用界面切换、图片轮询播放等场景。 二、QSt…

Linu网络服务NFS

linux网络服务NFS 一.NFS简介二.NFS原理三.NFS优势四.配置文件五.NFS共享存储服务的操作步骤 一.NFS简介 NFS&#xff08;网络文件服务&#xff09; NFS是一种基于tcp/ip传输的网络文件系统协议&#xff0c;最初由sun公司开放通过使用NFS协议&#xff0c;客户机可以像访问本地…

Java课题笔记~ ServletContext

单个Servlet的配置对象 web.xml <servlet><servlet-name>FirstServlet</servlet-name><servlet-class>com.ambow.test.FirstServlet</servlet-class><init-param><param-name>charset</param-name><param-value>utf-8&…

SpringMVC注解配置

1xml配置方式&#xff08;配置文件注解的方式&#xff09; 前提导入相关依赖&#xff1a;pom文件 说明&#xff1a;下方依赖是ssm项目中较为常用的一部分&#xff0c;可能部分依赖对于springmvc配置并未有关系&#xff0c;根据自己需求添加和删除。 <dependencies> &l…

新手如何快速学习单片机?

初步确定学习目标&#xff1a;是学习简单便宜的51呢&#xff0c;还是学习简单但是性价比已经不算太高的&#xff0c;但是功能强大稳定可靠的avr&#xff0c;还是物美价廉的stm32&#xff0c;或者ARM9&#xff08;可以跑系统了&#xff09;&#xff0c;再往上x86什么的如果是学8…

成员变量和局部变量的区别

局部变量成员变量 1、定义的位置不一样 在方法的内部&#xff0c;方法申明上&#xff08;形参&#xff09;。 声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量 在方法的外部&#xff0c;直接写在类当中 &#xff08;类中方法外的变量&#xff09; 2、作用范…

opencv 实现手势跟踪并返回位置信息(封装调用)

OpenCV 是一个基于 Apache2.0 许可&#xff08;开源&#xff09;发行的跨平台计算机视觉和机器学习软件库&#xff0c;可以运行在Linux、Windows、Android和Mac OS操作系统上。 需要提前准备opencv 和 mediapipe库 pip --default-timeout5000 install -i https://pypi.tuna.t…

什么是IMAP协议?

IMAP&#xff08;Internet Message Access Protocol&#xff09;是一个应用层协议&#xff0c;用于访问和管理存储在远程服务器上的电子邮件。相比于POP3&#xff0c;IMAP提供了更加丰富的功能&#xff0c;特别适用于需要在多台设备上访问电子邮件的用户。以下是关于IMAP的详细…

支持多用户协同的思维导图TeamMapper

什么是 TeamMapper &#xff1f; TeamMapper 是基于 Mindmapp 开发的用于绘制思维导图的 Web 应用程序。它使得思维导图变得简单&#xff0c;你可以托管并创建您自己的思维导图。与您的团队分享您的思维导图会议并在思维导图上进行协作。 软件特点&#xff1a; 创建&#xff1…

解决:Unexpected ‘debugger‘ statement.eslint(no-debugger) (即:页面中的 debugger 标红)的问题

1、问题描述&#xff1a; 其一、报错为&#xff1a; Unexpected debugger statement.eslint(no-debugger) 中文为&#xff1a; 意外的“调试器”语句.eslint&#xff08;无调试器&#xff09; 其二、问题描述为&#xff1a; 在正常的 vue 项目中使用 debugger 的调试过程…

人工智能原理(2)

目录 一、知识与知识表示 1、知识 2、知识表示 3、知识表示方法 二、谓词逻辑表示法 1、命题逻辑 2、谓词逻辑 三、产生式表达法 1、知识的表示方法 2、产生式系统组成 3、推理方式 4、产生式表示法特点 四、语义网络 1、概念及结构 2、语义网络的基本语义联系 …