草庐IT

Linux系统编程001--系统IO

emolife 2023-03-28 原文

1. 文件系统:用来存储、组织、管理文件的一套方式、协议

2. 文件

  • 文件的属性:i-node唯一表示一个文件的存在与否
  • 文件的内容

3. Linux系统如何实现文件的操作?

硬件层:
    inode(属性)--->文件的内容
Linux内核:
    struct inode{}用来描述一个文件的屋里inode的信息【链表保存】,系统识别到一个文件的存在,
    就会为它创建一个struct inode,一个文件只会唯一对应一个struct inode

    struct file{}用来描述一个已经打开的文件:
        文件状态标记(如:O_RDONLY、O_WRONLY......)
        文件的偏移量/offset(类似“光标”)

    struct inode*
        每一个打开的文件都会对应一个struct file
        一个文件可以被多个不同的进程打开,一个进程也可以打开多个文件

    操作文件的过程:
        struct file---> struct inode--->硬件上面的inode--->文件的内容
        linux为了屏蔽文件操作的具体细节,为每一个进程创建一个“进程文件表项”,
        保存每一个进程打开的文件的 struct file* 的数组
        struct file*fds[]
            0  struct file*--->struct inode......
            1  struct file*--->struct inode......
            ......

    linux再提供操作文件的函数接口:
        fd = open()
        打开一个指定的文件,返回“进程文件表项”的下标,
        int  "文件描述符":在linux应用中,用来描述一个已经打开的文件,每一个打开的文件都有有个唯一的id,
                            后续操作这个文件,都是通过这个id操作该文件
        read(fd)
        write(fd)
        close(fd)
        ......
    linux系统提供的这些用于操作文件的接口函数(open,read.....),我们称为“系统IO”
    系统IO:操作系统提供的对文件的输入输出的接口

4. Linux系统IO的使用

文件的操作步骤

  • 打开文件 open()
NAME
    open, openat, creat - open and possibly create a file
    打开或者创建(创建并打开)一个文件
SYNOPSIS
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    int open(const char *pathname, int flags);
    int open(const char *pathname, int flags, mode_t mode);
        pathname:要打开或者创建的文件名,带路径(不带路径表示当前路径) 
        flags:打开文件的标记
            O_RDONLY:只读
            O_WRONLY:只写
            O_RDWR:读写
            以上三个标记只能选一个(文件的打开方式)
            O_APPEND:追加标记,打开文件后,文件的偏移量会在文件的末尾。(默认情况下,读和写的标记在文件的开头)
            O_CREAT:创建标记,如果不存在,则创建文件
            O_EXCL:该标记一般和O_CREAT配合使用,用来测试文件是否存在
                    如果指定O_CREAT | O_EXCL,并且文件存在,则open会失败,并且errno设置为EEXIST,表示文件已存在
            O_TRUNC:truncate  截短,清除文件内容
            O_NONBLOCK:非阻塞方式打开文件
                        非阻塞:不等待
                        如果文件没有内容,read不会等待,直接返回一个错误
                        如果文件没有空间了,write不会阻塞,直接返回一个错误
                        阻塞:等待
                        如果文件没有内容,read会等待(直到有数据或出错)
                        如果文件没有空间了,write会阻塞,(直到有空间或出错)
                        。。。。。。
            多个标记使用“|”链接(标记是使用位域实现的)
            O_RDWR | O_CREAT | O_TRUNC
        mode:指定创建的文件的权限,当第二个参数带有O_CREAT时,指定创建的文件的权限
        返回值:成功打开一个文件,返回打开文件的文件描述符(>2 && int(下标))
        	  操作系统会自动为每一个进程打开三个文件:
        	  标准输入文件:文件描述符 STDIN_FILENO (0)
        	  标准输出文件:文件描述符 STDOUT_FILENO (1)
        	  标准出错文件:文件描述符 STDERR_FILENO (2)
        	  失败返回-1,同时errno被设置
     errno是一个全局变量,是用来保存最后一个出错的错误码
         头文件: #include<srrno.h>
         路径:/usr/include/errno.h
         perror 把错误码对应的错误字符串打印出来
         perro("user indi");
            user indi:用户自己的提示信息
        	打印出来的形式:用户自己的提示信息:系统错误码的提示信息
    int creat(const char *pathname, mode_t mode);
  • 对文件的操作(读、写...)
  • 关闭文件
//关闭文件
NAME
    close - close a file descriptor
SYNOPSIS
    #include <unistd.h>
    int close(int fd);
        close是用来关闭fd指定的文件
        fd:file descriptor 文件描述符
        返回值:
            成功:返回0
            失败:返回-1,同时errno被设置

 

有关Linux系统编程001--系统IO的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. 电脑0x0000001A蓝屏错误怎么U盘重装系统教学 - 2

      电脑0x0000001A蓝屏错误怎么U盘重装系统教学分享。有用户电脑开机之后遇到了系统蓝屏的情况。系统蓝屏问题很多时候都是系统bug,只有通过重装系统来进行解决。那么蓝屏问题如何通过U盘重装新系统来解决呢?来看看以下的详细操作方法教学吧。  准备工作:  1、U盘一个(尽量使用8G以上的U盘)。  2、一台正常联网可使用的电脑。  3、ghost或ISO系统镜像文件(Win10系统下载_Win10专业版_windows10正式版下载-系统之家)。  4、在本页面下载U盘启动盘制作工具:系统之家U盘启动工具。  U盘启动盘制作步骤:  注意:制作期间,U盘会被格式化,因此U盘中的重要文件请注

  5. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  6. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  7. 网络编程套接字 - 2

    网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识

  8. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  9. ruby - 我正在学习编程并选择了 Ruby。我应该升级到 Ruby 1.9 吗? - 2

    我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or

  10. ruby - 在没有基准或时间的情况下用 Ruby 测量用户时间或系统时间 - 2

    因为我现在正在做一些时间测量,我想知道是否可以在不使用Benchmark类或命令行实用程序time的情况下测量用户时间或系统时间。使用Time类只显示挂钟时间,而不显示系统和用户时间,但是我正在寻找具有相同灵active的解决方案,例如time=TimeUtility.now#somecodeuser,system,real=TimeUtility.now-time原因是我有点不喜欢Benchmark,因为它不能只返回数字(编辑:我错了-它可以。请参阅下面的答案。)。当然,我可以解析输出,但感觉不对。*NIX系统的time实用程序也应该可以解决我的问题,但我想知道是否已经在Ruby中实

随机推荐