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

news2024/11/19 17:19:42

本节学习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.coloradmin.cn/o/1661934.html

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

相关文章

【大学物理】东北大学-马文蔚听课笔记

4.1刚体的定轴转动_哔哩哔哩_bilibili 此笔记为课堂学习笔记~ 4.1刚体的定轴转动 基本教学要求 什么时刚体呢&#xff1f; 研究刚体运动切口 平动&#xff1a;刚体中所有的点的运动轨迹都完全相同。 转动&#xff1a;分为&#xffe5;定轴转动和非定轴转动 刚体转动的角速度…

人脸采集训练识别

项目概述&#xff1a; 本地摄像头采集人脸数据集&#xff0c;通过训练得到trainingData.yml模型&#xff0c;加载haarcascade_frontalface_default.xml实现人脸识别。haarcascade_frontalface_default.xml 文件并不是一个完整的人脸识别模型&#xff0c;而是一个用于检测正脸&a…

基于Spring Cloud的房产销售平台设计与实现

基于Spring Cloud的房产销售平台设计与实现 开发语言&#xff1a;Java 框架&#xff1a;SpringCloud JDK版本&#xff1a;JDK1.8 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台首页界面&#xff0c;前台首页包括房源信息、…

RS485空调系统到BACnet江森楼宇系统的高效整合攻略

智慧城市的每一栋建筑都在追求更高的能效与更佳的居住体验&#xff0c;而这一切的实现离不开强大且灵活的楼宇自动化系统。其中&#xff0c;协议转换网关作为连接不同设备的纽带&#xff0c;扮演着至关重要的角色。本文将以一个典型的商业综合体为例&#xff0c;揭秘BACnet协议…

零基础开发新闻小程序带评论点赞收藏功能,可以回复评论,借助小程序云开发云模板开发一款图文小程序,新闻列表新闻详情,登录注册功能

小程序官方有改版了&#xff0c;搞得石头哥不得不紧急的再新出一版&#xff0c;教大家开通最新版的cms网页管理后台 一&#xff0c;技术选型和技术点 1&#xff0c;小程序前端 wxml css JavaScript MINA原生小程序框架 2&#xff0c;数据库 云开发 云数据库 云…

力扣:62. 不同路径

62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&…

20232906 2023-2024-2 《网络与系统攻防技术》第九次作业

20232906 2023-2024-2 《网络与系统攻防技术》第九次作业 1.实验内容 本次实践的对象是一个名为pwn1的linux可执行文件。 该程序正常执行流程是&#xff1a;main调用foo函数,foo函数会简单回显任何用户输入的字符串。 该程序同时包含另一个代码片段&#xff0c;getShell&am…

【负载均衡式在线OJ项目day4】编译运行功能整合及打包网络服务

一.前言 前面两天完成了编译和运行两个子模块&#xff0c;今天的任务是完成CompileRun模块&#xff0c;它的任务如下&#xff1a; 解析来自客户端的Json字符串&#xff0c;反序列化提取编译运行需要的数据&#xff0c;即代码&#xff0c;时间限制和空间限制把代码写入临时文件…

太阳能无人机的多元化应用

随着新能源技术的不断发展和成熟&#xff0c;太阳能在无人机的应用技术已经成熟。太阳能无人机得到了量产和广泛的应用。传统无人机相比&#xff0c;太阳能无人机无需燃油&#xff0c;运行费用低廉&#xff0c;搭载多种高科技设备&#xff0c;能够高效、多元化地采集和分析各类…

公司活动想找媒体报道宣传怎样联系媒体?

作为公司宣传负责人,我深知媒体报道对于企业活动宣传的重要性。然而,在过去,每当有重要活动需要媒体曝光时,我总会被繁琐的媒体联系工作所困扰。 那时,我需要一家家地查询媒体联系方式,发送邮件、打电话,甚至亲自前往媒体机构进行沟通。然而,这样的过程不仅费时费力,而且效率低…

成本降低 90%,出海社交平台 Typing 基于 Databend 的大数据探

Typing&#xff08;输入中科技&#xff09;成立于 2022 年&#xff0c;是一家主要面向东南亚、拉美、中东等海外地区提供社交平台的出海企业。其社交平台类似于国内的 Soul、陌陌等&#xff0c;提供视频直播、语音聊天室、短视频、生活分享、文字聊天等社交功能&#xff0c;注册…

英语学习笔记5——Nice to meet you.

Nice to meet you. 很高兴见到你。 词汇 Vocabulary Mr. 先生 用法&#xff1a;自己全名 / 姓 例如&#xff1a;Mr. Zhang Mingdong 或 Mr. Zhang&#xff0c;绝对不能是 Mr. Mingdong&#xff01; Miss 女士&#xff0c;小姐 未婚 用法&#xff1a;自己全名 / 姓 例如&#…

区块链(打新)如何被割韭菜

看上去&#xff0c;像我只要去每个都买一遍新发行的代币&#xff0c;一定可以成功的 但是好像没有想象中这么简单&#xff0c;因为这些山寨币&#xff0c;庄家可以自己控盘的&#xff0c;看上去好像有跌宕起伏的买卖&#xff0c;但是一单掀桌子&#xff0c;庄家他自己都不玩了…

SOCKET编程(3):相关结构体与函数

相关结构体与函数 sockaddr、sockaddr_in结构体 sockaddr和sockaddr_in详解 struct sockaddr共16字节&#xff0c;协议族(family)占2字节&#xff0c;IP地址和端口号在sa_data字符数组中 /* Structure describing a generic socket address. */ struct sockaddr {__SOCKADDR…

推荐3个实用的github开源项目

目录&#xff1a; 1、AI生成高清短视频 2、媒体平台爬虫 3、文本转语音项目

ubuntu server 22.04 安装docker、docker-compose

ubuntu server 22.04安装docker有两种方式&#xff0c;第一种是使用ubuntu镜像源的软件包进行安装&#xff0c;第二种使用官方GPG密钥手动添加Docker存储库方式进行安装&#xff0c;两种方式都可以&#xff0c;但第二种方式略复杂&#xff0c;这里介绍第一种比较简单的安装方式…

图像ISP——AGC参数解析

前言 AWB和AGC是两种常见的自动调整功能。AWB用于自动调整图像的白平衡&#xff0c;以确保颜色在不同光照条件下仍然看起来自然。而AGC则用于自动调整图像的增益&#xff0c;以在不同的亮度条件下保持适当的曝光。 代码例程 static AWB_AGC_TABLE_S g_stAwbAgcTable {/* bvali…

深入解析Java中Set接口

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

【前端基础】CSS样式+Vue中绘制时间轴

深度选择器 在 Vue.js 中&#xff0c;/deep/、>>>、:deep 和 ::v-deep 这些都是深度选择器&#xff0c;用于修改子组件的样式。它们主要用于解决作用域样式和组件样式之间的冲突问题。 1. /deep/ 或 >>> /deep/ 和 >>> 是相同的选择器&#xff0c;…

spring boot参数验证注解@NotNull、@NotBlank和@NotEmpty区别

目录 前言说明举例 前言 使用spring boot参数验证是常常会使用NotNull、NotBlank和NotEmpty三个判断是否不为空的注解&#xff0c;中文都有不能为空的意思&#xff0c;大部分使用者都傻傻分清它们之间到底有什么区别。今天就让咱们来一起探索它们之间的不同吧。 说明 注解名…