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.hqwc.cn/news/685903.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp picker组件的样式更改

不知道有没有小伙伴遇到过这个问题 我是各种穿透和层级都尝试了更改不了其样式 梳理一下 H5端 在全局app.vue下添加如下代码 .uni-picker-container .uni-picker-header{ background-color: $uni-color-pink; //picker头部背景色}.uni-picker-container .…

ttkbootstrap界面美化系列之PanedWindow(七)

在界面设计中经常用PanedWindow控件来对整个界面进行切割布局&#xff0c;让整个界面看上去有层次感&#xff0c;不至于说杂乱无章。在我之前的文章中有对tkinter的该控件做了详细的介绍&#xff0c;链接如下基于Tkinter的PanedWindow组件进行窗口布局-CSDN博客 本文主要是介绍…

【进程替换】多进程程序替换原理 | 进程程序替换函数 | execlexecv | execlpexecvp

目录 多进程程序替换 多进程程序替换原理 进程程序替换函数详解 execl&execv execlp&execvp execle&execvpe execve 多进程程序替换 我们想要进程替换的同时不影响旧的进程&#xff08;使用多进程版&#xff09;fork创建子进程&#xff0c;让子进程去替换执…

并发问题系统学习(更新中)

进程、线程 进程&#xff1a;进程是代码在数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位。可以理解为一个java应用。 线程&#xff1a;线程是进程的一个执行路径&#xff0c;一个进程中至少有一个线程&#xff0c;进程中的多个线程共享进程的资源。…

2024.05.10作业

TCP服务器 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { class Widget; …

Paddle 基于ANN(全连接神经网络)的GAN(生成对抗网络)实现

什么是GAN GAN是生成对抗网络&#xff0c;将会根据一个随机向量&#xff0c;实现数据的生成&#xff08;如生成手写数字、生成文本等&#xff09;。 GAN的训练过程中&#xff0c;需要有一个生成器G和一个鉴别器D. 生成器用于生成数据&#xff0c;鉴定器用于鉴定数据的准确性&…

国产开源物联网操作系统

软件介绍 RT-Thread是一个开源、中立、社区化发展的物联网操作系统&#xff0c;采用C语言编写&#xff0c;具有易移植的特性。该项目提供完整版和Nano版以满足不同设备的资源需求。 功能特点 1.内核层 RT-Thread内核包括多线程调度、信号量、邮箱、消息队列、内存管理、定时器…

[c++]多态的分析

多态详细解读 多态的概念多态的构成条件 接口继承和实现继承: 多态的原理:动态绑定和静态绑定 多继承中的虚函数表 多态的概念 -通俗的来说&#xff1a;当不同的对象去完成某同一行为时&#xff0c;会产生不同的状态。 多态的构成条件 必须通过基类的指针或者引用调用虚函数1虚…

合并两个有序链表(C语言)———链表经典算法题

题目描述​​​​​​21. 合并两个有序链表 - 力扣&#xff08;LeetCode&#xff09;&#xff1a; 答案展示: 迭代&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* mergeTwoLis…

【docker 】push 镜像到私服

查看镜像 docker images把这个hello-world 推送到私服 docker push hello-world:latest 报错了。不能推送。需要标记镜像 标记Docker镜像 docker tag hello-world:latest 192.168.2.1:5000/hello-world:latest 将Docker镜像推送到私服 docker push 192.168.2.1:5000/hello…

【吃透Java手写】2-Spring(下)-AOP-事务及传播原理

【吃透Java手写】Spring&#xff08;下&#xff09;AOP-事务及传播原理 6 AOP模拟实现6.1 AOP工作流程6.2 定义dao接口与实现类6.3 初始化后逻辑6.4 原生Spring的方法6.4.1 实现类6.4.2 定义通知类&#xff0c;定义切入点表达式、配置切面6.4.3 在配置类中进行Spring注解包扫描…

python中如何把list变成字符串

python中如何把list变成字符串&#xff1f;方法如下&#xff1a; python中list可以直接转字符串&#xff0c;例如&#xff1a; data ["hello", "world"] print(data1:,str(data)) 得到结果&#xff1a; (data1:, "[hello, world]") 这里将整个…