Linux应用(四)——系统IO函数

本节学习linux系统中常见的IO函数,讲解及其基本用法;

一、 open/close函数

open函数作用:系统调用open函数,打开指定路径的文件;

 int open(const char *pathname, int flags);打开一个存在的文件;

 int open(const char *pathname, int flags, mode_t mode);创建一个新的文件;

 int open(const char *pathname, int flags, mode_t mode);

       参数:

         pathname:要创建(打开)文件的路径;

          flags:对文件的操作权限和其他的设置

                必选项: O_RDONLY, O_WRONLY, or O_RDWR.之间互斥;

                可选项:  O_CREAT  文件不存在会创建新文件;

        mode:必须是一个8进制的数,表示创建新的文件的操作权限;例如:0775;

        最终的权限是:  the mode of the created file is (mode & ~umask).umask:0002;0775;

        为什么是0777?rwx都为1,三组;

        0777    111111111

        0775    111111101

        umask的作用:抹去某些权限。

返回值:返回一个新的文件描述符;如果失败则返回-1;

errno:属于linux系统函数库,库里面的一个全局变量,记录的是最近的错误号。

利用perror函数能够将errno错误的原因打印出来;

#include<stdio.h>

void perror(const char*s);作用:打印 errno对应的错误描述

        s参数:用户描述,比如hello,最终打印的结果是 hello:XXX(实际错误的具体原因);

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>     
int main()
{
//创建一个新的文件,通过open调用;

   int fd= open("creat.txt",O_RDWR|O_CREAT,0777);
   if(fd==-1)
   {
        perror("open");
   }
   //关闭文件描述
    close(fd);
    return 0;

}

close函数:关闭文件,传入的参数是一个文件描述符;   

#include <unistd.h> 

         close(fd);

二、read/write函数

read函数:把文件的数据读到内存中;

write函数:把内存中的数据写到文件中;

利用read、write函数完成文件的复制;

read函数:

linux中对于read函数的介绍(man 2 read)

涉及的头文件:

#include <unistd.h>

    ssize_t read(int fd, void *buf, size_t count);

    参数:

        fd:文件描述符,open得到的;通过文件描述符操作某个文件;

        buf:需要读取数据存放的地方;数组的地址;传出参数;

        count:指定的数组的大小;

    返回值:

            成功,返回

            >0:返回实际的读取到的字节数;

            =0:文件已经读取完成了;

            失败:返回-1,并且设置errno,通过perror可以读取错误;

write函数

linux中对于read函数的介绍(man 2 write)

涉及的头文件: 

#include <unistd.h>

       ssize_t write(int fd, const void *buf, size_t count);

   参数: fd:文件描述符,open得到的;通过文件描述符操作某个文件;

           buf:要往磁盘写入的数据;

           count:要写的数据的实际大小;

 返回值:

           成功,实际写入的字节数;

           失败:返回-1,设置errno;

实现功能:

        现有一个english.txt文件,通过read函数读取TXT文件的值,再通过write函数将TXT文件中的值复制到一个新的文件中;

实现流程:
1、  通过open打开english.txt文件;

2、  创建一个新的文件,拷贝文件;

3、  频繁的读写操作;

4、  关闭文件

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

int main()
{
    int srcfd= open("english.txt", O_RDONLY);
    if(srcfd==-1)
    {
                perror("open");
                return -1;
    }
    //通过open打开english.txt文件;

    int  destfd = open("cpy.txt", O_WRONLY|O_CREAT,0664);
    if(destfd ==-1)
    {
                perror("open");
                return -1;
    }
    //创建一个新的文件,拷贝文件;

    char buf[1024]={0};
     int len= 0; 
     while((len=read(srcfd, buf, sizeof(buf)))>0)
     {
        write(destfd,buf,len);
     }
    //频繁的读写操作;
  
    close(destfd);
    close(srcfd);
    //关闭文件;
    return 0;

}

三、lseek函数

lseek函数:主要用作文件指针的偏移;

read函数:

linux中对于lseek函数的介绍(man 2 lseek)

 Linux系统函数

涉及的头文件:

       #include <sys/types.h>

       #include <unistd.h>

       off_t lseek(int fd, off_t offset, int whence);

        参数:

        fd:文件描述符,通过open得到,通过这个fd操作某个文件;

        offset:偏移量;

        whence:

         SEEK_SET

         设置文件指针的偏移量,从文件头开始偏移;

              The file offset is set to offset bytes.

       SEEK_CUR

        设置偏移量;当前位置+第二个参数offset的值;

              The file offset is set to its current location plus offset bytes.

       SEEK_END

        设置偏移量:文件的大小+第二个参数offset的值;

              The file offset is set to the size of the file plus offset bytes.

        返回值:返回文件指针的位置;

              函数作用:

              1、移动文件指针到头文件;lseek(fd,0, SEEK_SET);例如:文件反复从头文件开始读;

              2、获取当前文件指针的位置:lseek(fd,0,SEEK_CUR);返回值:返回最终文件指针的位置;

              3、获取文件长度lseek(fd,0,SEEK_END);从文件末尾偏移0个单位;

              4、可以拓展文件的长度:当前文件10b,准备拓展为110b,增加了100个字节;

              lseek(fd,100,SEEK_END);只进行了指针的移动,还需要写入一次才管用;

实现功能:

        现有一个hello.txt文件,其为11个字节,现在通过lseek函数进行扩展,多余扩展100个字节;

实现流程:
1、  通过open打开hello.txt文件;

2、  扩展文件长度

3、  写入一个空数据;

4、  关闭文件

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

       int main()
       {
           int fd= open("hello.txt",O_RDWR);
           if(fd==-1)
           {
            perror("open");
            return -1;
           }
           //扩展文件长度:
         int ret = lseek(fd,100,SEEK_END);
           if(ret==-1)
           {
                  perror("lseek");
                  return -1;
           }
           //写入一个空数据

           write(fd," ",1);
           //关闭文件;
            close(fd);

            return 0;
       }

 注意:此处我们为什么要在 扩展文件长度后,再写入一个空数据呢?

      因为我们利用lseek函数,只能将文件指针的位置进行后移,并不能进行文件的扩展,在文件指针后移的位置,写入一个字节,才能完成整个文件的扩展。

四、stat/lstat函数

stat函数:用于获取文件的相关信息;

lstat函数:获取软连接文件的相关信息;

linux 中对于是stat函数的说明:

Linux系统函数:

 stat:

涉及的头文件:

       #include <sys/types.h>

       #include <sys/stat.h>

       #include <unistd.h>

主要作用与参数:

        //作用:获取一个文件相关的信息;返回文件相关的一个信息;

       //参数:

            pathname:操作文件的路径;获取哪个文件的信息呢?

            statbuf:结构体变量,传出参数,用于保存获取到的信息;

st_mode变量:

     

 返回值:

        成功:返回0;

        失败:返回-1;

        通过errno打印错误原因;

       int lstat(const char *pathname, struct stat *statbuf);

       软连接文件。如果用stat获取软连接的文件,其实获取的是指向的文件的内容;

       如果要获取软连接的文件就要用lstat;

实现功能:获取某个文件的相关文件信息;

现有一a.txt文件,其内容如下所示:

编辑以下代码:读取文件的大小;

       #include <sys/types.h>
       #include <sys/stat.h>
       #include <unistd.h>
       #include <stdio.h>
int main()
{
       struct stat statbuf;
      
      int ret = stat("a.txt",&statbuf);
       if(ret ==-1)
       {
              perror("stat");
              return -1;
       }
       printf("size:%ld\n",statbuf.st_size);
       return 0
}

五、模拟实现ls -l命令

如下图所示,我们经常使用ls -l指令对一个文件进行属性信息的查询;查询的内容主要包括:文件的类型和权限、文件所在的组、硬链接数、文件所有者、文件大小、文件修改的时间;

例如:下图中:-rw-rw-r-- 1 nowcoder nowcoder 12 4-р с 29 11:13 a.txt

     我们本节所有实现的代码功能:即运行一个代码+文件名称,然后打印出ls-l命令所展示出来的信息:


//模拟实现ls -l指令
//-rw-rw-r-- 1 nowcoder nowcoder 12 4-р с 29 11:13 a.txt
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <string.h>
int main(int argc,char * argv[])
{
    //判断输入的参数是否正确,如果不正确,则给出提示;
    if(argc<2)
    {
        printf("%s filename\n",argv[0]);
        return -1;
    }
    //通过stat函数获取文件的信息
   struct stat st;
    int ret=stat(argv[1],&st);
    if(ret==-1)
    {
        perror("stat");
        return -1;

    }
//获取文件类型和文件权限
    char perms [11]={0};//用于保存文件类型和文件权限的字符数组;
    switch(st.st_mode & __S_IFMT)
    {
        case __S_IFLNK:
             perms[0]='l';
            break;
        case __S_IFDIR:
             perms[0]='d';
            break;
        case __S_IFREG:
             perms[0]='-';
            break;
        case __S_IFBLK:
             perms[0]='b';
            break;
        case __S_IFCHR:
             perms[0]='c';
            break;
        case __S_IFSOCK:
             perms[0]='s';
            break;
        case __S_IFIFO:
             perms[0]='p';
            break;
        default :
             perms[0]='?';
            break;
    }

    //判断文件的访问权限
    perms[1]=(st.st_mode & S_IRUSR )? 'r':'-';
    perms[2]=(st.st_mode & S_IWUSR )? 'w':'-';
    perms[3]=(st.st_mode & S_IXUSR )? 'x':'-';
    
    //判断文件所在组
    perms[4]=(st.st_mode & S_IRGRP )? 'r':'-';
    perms[5]=(st.st_mode & S_IWGRP )? 'w':'-';
    perms[6]=(st.st_mode & S_IXGRP )? 'x':'-';

     //其他人
    perms[7]=(st.st_mode & S_IROTH )? 'r':'-';
    perms[8]=(st.st_mode & S_IWOTH )? 'w':'-';
    perms[9]=(st.st_mode & S_IXOTH )? 'x':'-';

    //硬链接数
    int linknum = st.st_nlink;

    //文件所有者
   char * fileuser = getpwuid(st.st_uid)->pw_name; 
   //文件所在组
   char * groupuser = getgrgid(st.st_gid)->gr_name;

   //文件大小
   long int filesize = st.st_size;

   //获取修改的时间
   char * time = ctime(& st.st_mtime) ; 
   char  mtime[512]={0};

   strncpy(mtime,time,strlen(time)-1);

   char buf[1024];
   sprintf(buf,"%s %d %s %s %ld %s %s", perms,linknum,fileuser,groupuser,filesize,mtime,argv[1]);
   printf("%s\n",buf);

    return 0;

}

 其运行结果:

总结:本节介绍的是linux系统中常见的IO函数的介绍与使用;对基本功能、基本使用以及举例说明的方式对于IO函数做了讲解。

创作不易,还请大家多多点赞支持!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenNJet,够轻更强云原生应用引擎

前言&#xff1a; 在正式介绍OpenNJet之前&#xff0c;我们先来看看它的技术架构&#xff0c;如下图所示&#xff0c;OpenNJet正是NGINX的Pro版&#xff0c;在100%兼容NGINX基础上&#xff0c;新增了动态配置加载、主动式健康检测、集群高可用、声明式API等多种强大功能。 NGIN…

第十一讲:指针(3)

第十一讲&#xff1a;指针&#xff08;3&#xff09; 1.字符指针变量1.1存储一个字符1.2存储一个字符串1.3一个有趣的面试题 2.数组指针变量2.1什么是数组指针变量2.2数组指针变量的初始化 3.二维数组传参的本质4.函数指针变量4.1介绍函数指针变量4.2 两段有趣的代码4.2.1代码1…

华为 Huawei 交换机 配置 Dot1q 终结子接口实现同设备 VLAN 间通信示例

组网需求 企业的不同部门拥有相同的业务&#xff0c;如上网、 VoIP 等业务&#xff0c;且各个部门中的用户位于不同的网段。目前存在不同的部门中相同的业务所属的VLAN 不相同&#xff0c;现需要实现不同VLAN中的用户相互通信。 如 图 7-7 所示&#xff0c;部门 1 和部门 2 中…

机器学习的一些知识点分享

下面数据集中&#xff0c;第2个样本的第4个属性的值是&#xff08; &#xff09;。 A 52 B 男 C 50 D 49 本题得分&#xff1a; 2分 正确答案&#xff1a; D 2.单选题 (2分) 10-折交叉验证是把数据集分成&#xff08; &#xff09;个子集&#xff0c;将其中&#xff…

好景盒式磁带随声听

少年时代柜子里翻出来的磁带录音机电路板 两颗芯片&#xff0c;FM芯片&#xff0c;电机驱动 CD9088CBD6650

第十三届蓝桥杯决赛(国赛)真题 Java C 组【原卷】

文章目录 发现宝藏试题 A: 斐波那契与 7试题 B: 小蓝做实验试题 C: 取模试题 D: 内存空间试题 E \mathrm{E} E : 斐波那契数组试题 F: 最大公约数试题 G: 交通信号试题 I: 打折试题 J: 宝石收集 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#x…

VM虚假机联网(无代码,超简单)NAT模式

1、左边顶上编辑里面最下面找到虚拟网络编辑器2.启用管理员特权3.重新创建一个NAT模式的网络&#xff08;名称随便一个&#xff09; 4.打开这两个设置里面的东西进行拍照并记住IP区间和网关&#xff0c;等下要用&#xff1b; 5.打开虚拟机&#xff0c;右上角&#xff0c;下标点…

sql注入中的替换技巧。

目录 1&#xff1a;注释的替换 2&#xff1a;空格替换 3&#xff1a;大小写混合绕过及双写绕过 4&#xff1a;等号的绕过 5&#xff1a;单双引号的绕过 1&#xff1a;注释的替换 注释在sql注入中非常重要&#xff0c;因为会使用它来闭合我们注入的sql语句。 当以get方式提…

idea运行项目报错提示:java: 错误: 不支持发行版本 19,让我来看看

在项目经常切换jdk时&#xff0c;这个error经常能遇到“不支持发行版本19”&#xff0c;这个问题修改起来其实很简单&#xff0c;但在真正操作到能够解决问题的那一步前&#xff0c;通常习惯先去查看配置的jdk版本是否是选择正确的&#xff0c;也就是先确认当前这个项目选择的j…

【全部更新】2024数维杯B题详细成品文章代码思路结果分享

生物质和煤共热解问题的研究 摘要 这个问题背景主要涉及生物质和煤共热解的研究。在共热解过程中&#xff0c;生物质和煤一起在高温和缺氧条件下热解&#xff0c;产生气体、液体和固体产物。研究生物质和煤共热解油的产率和品质机理对提高能源利用效率、促进资源综合利用和确保…

该问题未得到解决(仅记录)

https://releases.ubuntu.com/bionic/进入网页下载ubuntu 选择烧录软件将下载的Ubuntu烧录到U盘中 之前用这个U盘烧录过一次&#xff0c;成功了&#xff0c;后来应该是U盘受损或者是什么其他原因使得用这个U盘总是烧录失败

关于Ardupilot的固定翼(plane)的控制

起因 由于项目原来是使用的四旋翼,并且是PX4版本的四旋翼; 如今需要对无人机固定翼进行控制,并要求使用Ardupilot的固件进行研究。 特定在此记录对固定翼的学习,以和大家分享观点和交流学习。 PX4和Ardupilot关系 PX4和Ardupilot都是固件,固件就是软件的意思。两者都是…

重载,重写,重定义,纯虚函数,多态习题

只要不够成重写就是重定义。 重定义&#xff1a; 抽象类&#xff1a; 包含纯虚函数的类就是抽象类。 1.纯虚函数的作用&#xff0c;强制子类去完成重写。 2.表示抽象的类型。 抽象就是在现实中没有对应的实体。 1. 下面哪种面向对象的方法可以让你变得富有( a) A 继承 B…

四、用nodejs写新增接口

&#xff08;1&#xff09;新增数据库 选择不区分大小写 在新建查询内编译 &#xff08;2&#xff09;新建提交代码的表 create TABLE code_record( id INT not null auto_increment, name VARCHAR(200) not null, course VARCHAR(200) not null, mail VARCHAR(200) not null…

Spring框架学习笔记(二):Spring IOC容器配置 Bean,分别基于XML配置bean 和 基于注解配置 bean

1 Spring 配置/管理 bean 介绍 Bean 管理包括两方面 &#xff1a;创建 bean 对象&#xff1b;给 bean 注入属性 Bean 配置方式&#xff1a;基于 xml 文件配置方式&#xff1b;基于注解方式 2 基于 XML 配置 bean 2.1 通过类型来获取 bean 方法&#xff1a;给getBean传入一…

传输层之 TCP 协议

TCP协议段格式 源/目的端口号&#xff1a;表示数据是从哪个进程来&#xff0c;到哪个进程去。 序号&#xff1a;发送数据的序号。 确认序号&#xff1a;应答报文的序号&#xff0c;用来回复发送方的。 4 位首部长度&#xff1a;一个 TCP 报头&#xff0c;长度是可变的&#xff…

STM32学习和实践笔记(25):USART(通用同步、异步收发器)

一&#xff0c;STM32的USART简介 USART即通用同步、异步收发器&#xff0c;它能够灵活地与外部设备进行全双工数据交换&#xff0c;满足外部设备对工业标准 NRZ 异步串行数据格式的要求。 UART即通用异步收发器&#xff0c;它是在USART基础上裁剪掉了同步通信功能。 开发板上…

【Web】CTFSHOW 七夕杯 题解

目录 web签到 easy_calc easy_cmd web签到 CTF中字符长度限制下的命令执行 rce(7字符5字符4字符)汇总_ctf中字符长度限制下的命令执行 5个字符-CSDN博客7长度限制直接梭了 也可以打临时文件RCE import requestsurl "http://4ae13f1e-8e42-4afa-a6a6-1076acd08211.c…

Vision Mamba:高效视觉表示学习双向状态空间模型,超越Vision Transformer!

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; Vision Mamba: Efficient Visual Representation Learning with Bidirectional State Space Model 引言&#xff1a;探索视觉领域的新方向 在计算机视觉领域&…

翻工第二次 Ant Design Pro 下载,发现问题,电脑网络配置有误,魔法了

一、相关网址链接 鱼皮的用户中心项目 &#xff08;前端Ant Design Pro构建&#xff09; 语雀 ## 没有选择umi版本这一步 Issue #11144 ant-design/ant-design-pro GitHub 关于umi ui图标未显示问题_umi ui不出现-CSDN博客 二、存在问题 导致下载速度慢 本人镜像代码写…