Linux学习之系统编程1(关于读写系统函数)

写在前面:

我的Linux的学习之路非常坎坷。第一次学习Linux是在大一下的开学没多久,结果因为不会安装VMware就无疾而终了,可以说是没开始就失败了。第二次学习Linux是在大一下快放暑假(那个时候刚刚过完考试周),我没什么事做就又重拾Linux,不服输的我选择再战Linux,这一次学习还算顺利,虽然中间有些小插曲但是不影响整体学习进度, 我看着B站上的视频一点点学习Linux,基本上把Linux的基础指令学完了。学完之后我又遇到问题了,视频基本上到这就结束了,而我却不知道下一步该学什么,于是就没怎么碰Linux,结果没过多长时间我就把学的Linux指令忘的一干二净。现在是我第三次学习Linux,我决定重新开始学Linux,同时为了让自己学习的效果更好,我选择以写blog的形式逼迫自己每天把学习到的Linux知识整理下来。这也就是我写这个系列blog的原因。


好久没更新了,虽然这几天我并没有停止学习Linux,但是时间确实有点不够,写一篇blog还是比较耗时间的。(好吧,其实就是我有点懒,明明可以挤出时间,但是还是去划水了)


open函数

当遇到我们不熟悉的函数,我们可以去manpage查看,这也是一个非常重要的自主学习手段和方法

manpage 第二卷,直接man 2 open就可以查看open函数的的详细信息。
open1

根据上面的描述,我们可以得知open的基本信息

  • 要使用open需要引头文件sys/types.hsys/stat.h>fcntl.h(其中sys/types.hsys/stat.h>这两个头文件可以用unistd.h来替代。
  • 传入的第一个参数类型是const char*,看名称就可以猜到是要打开文件的路径,这里用绝对路径和相对路径都可以。
  • 传入的第二个参数类型是int,这里没有详细写,我就简单介绍,这个flag是权限控制,有O_RDONLY O_WRONLY O_RDWR,分别表示只读,只写,读写。(其实和C语言里的库函数fopen差不多)
  • 对于第二个open就是多了个参数mode_t mode,就是当文件不存在时,我们创建文件(前面那个flag参数还要指定O_CREAT才可以创建文件),指定文件的权限。(文件权限=mode&~umask)

关于返回值

open2
简单来说就是一个文件描述符,用它可以读写文件。这里实在理解不了的,可以把它理解成一个非负整数,用它来操作文件,后面我会详细讲解这个文件描述符。

使用open常见的错误

  • 打开文件不存在
  • 以写方式打开只读文件(权限问题)
  • 以只写方式打开目录

下面我举例演示

源代码:

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>

int main()
{
	int fd;
	fd=open("./test.c",O_RDONLY);
	if(fd<0)
	{
		printf("fd=%d,errno=%d:%s",fd,errno,strerror(errno));
		exit(0);
	}
	printf("fd=%d\n",fd);
	close(fd);
	return 0;
}

执行结果:
open3


close函数

学会了open函数,这个函数就没什么好说的。很简单。直接上图。
close


read函数

还是先查man 2 read,直接上图。
read
其实这个函数也没啥好说的,和C语言的标库函数差不多。从一个文件中读取。

参数解读

  • 第一个fd就是上面我们在open中学的返回值,一个文件描述符,用来操作文件。
  • 第二个buf,就是缓冲区,用来接收从fd文件中读取的内容。
  • 第三个count,就是从文件中读取的字节数。

返回值

  • 如果读取成功,就返回读取到的字节数。
  • 如果返回0,不代表读取失败,而是表示读取到文件的末尾了。
  • 如果读取失败,返回-1,并且errno被设置。

特别提醒:每次读取文件的偏移量都会移动相应的读取的字节数。(原文是the file position is advanced by this number)


write函数

还是先查man 2 write,直接上图。
write
read差不多

参数解读

  • 第一个fd就是上面我们在open中学的返回值,一个文件描述符,用来操作文件。
  • 第二个buf,就是缓冲区,里面是要写入fd文件中的内容。
  • 第三个count,就是从文件中写入的字节数。

返回值

  • 如果写入成功,就返回写入到的字节数。
  • 如果写入失败,返回-1,并且errno被设置。

特别提醒:要写入文件时,一定打开相应的权限O_WRONLY,同时要确保当前用户有权限向文件写入(即该用户对该文件有w权限)


利用readwrite来实现cp功能

先来说一说思路,我们先打开被复制的文件,用fd1来表示它,再创建复制后的文件。用fd2来表示。每次都用readfd1读取,再直接用write写入fd2即可。
废话少说,直接上源代码:

#include<unistd.h>
#include<errno.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>

int main(int argc,char* argv[])
{
        int fd1,fd2,n;
        char buf[4096];
        fd1=open(argv[1],O_RDONLY);
        fd2=open(argv[2],O_RDWR | O_CREAT,0664);
        if(fd1<0 || fd2<0)
        {
                printf("errno:%d:%s",errno,strerror(errno));
                exit(1);
        }
        while((n=read(fd1,buf,1024))!=0)
                write(fd2,buf,n);
        close(fd1);
        close(fd2);
        return 0;
}

效果如图
cp


预读入和缓输出

废话少说,先上图。
1


2
标准IO函数自带用户缓冲区,系统调用无用户级缓冲。可能上面的图各位童鞋看不懂,没关系,记住“系统函数并不是一定比库函数牛逼,能使用库函数的地方就使用库函数。


文件描述符

1
文件描述符的本质是指向文件结构体的指针。
PCB进程控制块:本质 结构体
成员: 文件描述符表。
文件描述符:0/1/2/3/4…/1023 表中可用的最小的。

0 - STDIN_FILENO
1 - STDOUT_FILENO
2 - STDERR_FILENO


lseek函数

还是先查看man 2 lseek
1

参数解读

  • fd应该很熟悉了吧,传要操作的文件。
  • offset是偏移量,就是你要文件移动的偏移量。
  • whence总共有三个值可以设定。SEEK_SET表示文件的开头,SEEK_CUR表示文件的当前的偏移量,SEEK_END表示文件的末尾。

返回值

返回值是个整数,表示当前文件的位置和开头的偏移量。

注意点

  1. 文件的“读”和“写”使用同一偏移量。
  2. 可以使用lseek获取大小
  3. 使用lseek拓展文件大小,但想真正引起文件大小变化,必须IO操作 。(这不是正规军的打法,正规军是应该是tuncate来拓展文件大小)

利用lseek获取文件大小

源代码:

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>

int main(int argc,char* argv[])
{
        int fd,res;
        fd=open(argv[1],O_RDONLY);
        if(fd<0)
        {
                perror("open file");
                exit(1);
        }
        res=lseek(fd,0,SEEK_END);
        printf("%s size is %d\n",argv[1],res);
        return 0;
}

效果:
2


目录项和 inode

1

一个文件主要由两部分组成,dentry(目录项)和 inode
inode 本质是结构体,存储文件的属性信息,如:权限、类型、大小、时间、用户、盘快位置…也叫做文件属性管理结构,大多数的 inode 都存储在磁盘上。少量常用、近期使用的inode 会被缓存到内存中。
所谓的删除文件,就是删除inode,但是数据其实还是在硬盘上,以后会覆盖掉。


stat 函数

还是先查看man 2 stat
1

参数解读

  • pathname看名字就知道是文件的路径。
  • statbuf这个参数类型是struct stat,虽然是第一次见,我这里简单介绍一下,包含文件各种信息的结构。

返回值

  • 成功返回0
  • 失败返回-1,errno被设置

关于struct stat

2

举例

源代码:

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

int main(int argc,char* argv[])
{
        struct stat sbf;
        stat(argv[1],&sbf);
        printf("The file size is %ld\n",sbf.st_size);
        if(S_ISREG(sbf.st_mode))
                printf("It is a regular file\n");
        else if (S_ISDIR(sbf.st_mode))
                printf("It is a directory\n");
        else
                printf("unkown file\n");
        return 0;
}

结果:
3


link函数和unlink函数

1

硬链接数就是 dentry 数目
link 就是用来创建硬链接的
link 可以用来实现 mv 命令

删除一个链接 int unlink(const char *pathname)

unlink 是删除一个文件的目录项 dentry,使硬链接数-1
unlink 函数的特征:清除文件时,如果文件的硬链接数到 0 了,没有 dentry 对应,但该文件仍不会
马上被释放,要等到所有打开文件的进程关闭该文件,系统才会挑时间将该文件释放掉。

由于这个函数比较简单,我这里就不赘述了。


目录操作函数

我这里就介绍三个最常用的函数:opendir readdir closedir
1


2
接下来我来用这几个函数来模拟实现Linux中的ls的功能来让具体体现这几个函数的用法


实现Linux的ls功能

源代码

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

void is_file(char*);

void read_dir(char* dir)
{
        char path[256];
        DIR* dp;
        struct dirent* sdp;
        dp=opendir(dir);
        if(dp==NULL)
        {
                perror("opendir error");
                return;
        }
        while((sdp=readdir(dp))!=NULL)
        {
                if(strcmp(".",sdp->d_name)==0 || strcmp("..",sdp->d_name)==0)
                        continue;
                sprintf(path,"%s/%s",dir,sdp->d_name);
                is_file(path);
        }
        closedir(dp);
        return;
}


void is_file(char* name)
{
        int ret;
        struct stat sb;
        ret=stat(name,&sb);
        if(ret==-1)
        {
                perror("stat error");
                return;
        }
}

int main(int argc,char* argv[])
{
        if(argc==1)
                is_file(".");
        else
                is_file(argv[1]);
        return 0;
}

效果展示
3


写在最后

个人亲身经验:我们学习的一系列Linux命令,一定要自己亲手去敲。不要只是看别人敲代码,不要只是停留在眼睛看,脑袋以为自己懂了,等你实际上手去敲会发现许许多多的这样那样的问题。正可谓“键盘敲烂,月薪过万


如果你觉得我写的题解还不错的,请各位王子公主移步到我的其他题解看看

  1. 数据结构与算法部分(还在更新中):
  • C++ STL总结 - 基于算法竞赛(强力推荐
  • 动态规划——01背包问题
  • 动态规划——完全背包问题
  • 动态规划——多重背包问题
  • 动态规划——分组背包问题
  • 动态规划——最长上升子序列(LIS)
  • 二叉树的中序遍历(三种方法)
  • 最长回文子串
  • 最短路算法——Dijkstra(C++实现)
  • 最短路算法———Bellman_Ford算法(C++实现)
  • 最短路算法———SPFA算法(C++实现)
  • 最小生成树算法———prim算法(C++实现)
  • 最小生成树算法———Kruskal算法(C++实现)
  • 染色法判断二分图(C++实现)
  1. Linux部分(还在更新中):
  • Linux学习之初识Linux
  • Linux学习之命令行基础操作
  • Linux学习之基础命令(适合小白)
  • Linux学习之权限管理和用户管理

✨🎉总结

“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”
在这里插入图片描述
如果有错误❌,欢迎指正哟😋

🎉如果觉得收获满满,可以动动小手,点点赞👍,支持一下哟🎉

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

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

相关文章

基于Java在线商城系统设计实现(源码+部署文档+讲解视频)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌&#x1f345; 文末获取源码联系 &#x1f345;&#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

目标检测-Two Stage-Mask RCNN

文章目录 前言一、Mask RCNN的网络结构和流程二、Mask RCNN的创新点总结 前言 前文目标检测-Two Stage-Faster RCNN提到了Faster RCNN主要缺点是&#xff1a; ROI Pooling有两次量化操作&#xff0c;会引入误差影响精度 Mask RCNN针对这一缺点做了改进&#xff0c;此外Mask …

Airtest的iOS实用接口介绍

前段时间Airtest更新了1.3.0.1版本&#xff0c;里面涉及非常多的iOS功能新增和改动&#xff0c;今天想详细跟大家聊一下里面的iOS设备接口。 PS&#xff1a;本文示例均使用本地连接的iOS设备&#xff0c;Airtest版本为1.3.0.1 。 安装接口&#xff1a;install、install_app …

使用css实现 Typora markdown 标题自动编号

第一&#xff0c;找到主题文件夹 第二&#xff0c;复制下面代码放入 AutoNumber.css文件中 body {counter-reset: h1; }#write h1, .markdown-section h1 {counter-reset: h2; }#write h2, .markdown-section h2 {counter-reset: h3; }#write h3, .markdown-section h3 {counte…

2023 NCTF writeup

CRYPTO Sign 直接给了fx,gx&#xff0c;等于私钥给了&#xff0c;直接套代码&#xff0c;具体可以参考&#xff1a; https://0xffff.one/d/1424 fx [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…

linux调试笔记

文章目录 基本启动调试与附加进程断点程序运行控制tui模式查看堆栈与变量监视变量多线程调试 扩展自定义跳转命令解析自定义类型禁用动态库自动加载设置源码路径断点时执行命令gdbserver远程调试 gdb脚本QtCreator调试Linux下处理编译、运行时的一些问题undefined symbol问题-n…

【C# 技术】 C# 常用排序方式——自定义数据排序

C# 常用排序方式——自定义数据排序 前言 在最近的项目中经常会对C#中的数据进行排序&#xff0c;对于基本数据类型&#xff0c;其排序方式比较简单&#xff0c;只需要调用内置算法即可实现&#xff0c;但对于自定义数据类型以及自定义排序规则的情况实现起来就比较麻烦&…

.NET Core中灵活使用反射

前言 前段时间有朋友问道一个这样的问题&#xff0c;.NET Core中如何通过Attribute的元数据信息来调用标记的对应方法。我第一时间想到的就是通过C#反射获取带有Custom Attribute标记的类&#xff0c;然后通过依赖注入&#xff08;DI&#xff09;的方式获取对应服务的方法并通…

D47|动态规划-子序列part2

392.判断子序列&#xff1a; 初始思路&#xff1a; 左为判断公共子序列&#xff0c;右为判断子序列&#xff0c;感觉代码完全可以套用&#xff0c;如果公共子序列的长度是较短的字符串的长度的话即输出true&#xff0c;如果不是即输出false。 class Solution {public boolean…

【openlayers-5】地图点、线、面等要素添加

1、添加点 //创建一个点 var point new ol.Feature({geometry: new ol.geom.Point([117.2, 35.8] ),}) //设置点的样式信息 point.setStyle(new ol.style.Style({//填充色fill: new ol.style.Fill({color: rgba(255, 255, 255, 0.2),}),//边线颜色stroke: new ol.style.Strok…

Unity坦克大战开发全流程——游戏场景——游戏界面——设置界面复用

游戏场景——游戏界面——设置界面复用 先将开始场景当中的设置面板复制过来 由于设置面板挂载的脚本都是相同的&#xff0c;在BeginScene中关闭设置面板时不会报空&#xff0c;而在GameScene中关闭设置面板时却会报空&#xff0c;这是因为监听事件中的单例模式调用的实例是Beg…

68内网安全-域横向PTHPTKPTT哈希票据传递

今天讲PTH&PTK&PTT&#xff0c; PTH(pass the hash) #利用 lm 或 ntlm 的值进行的渗透测试 PTT(pass the ticket) #利用的票据凭证 TGT 进行的渗透测试 用的Kerberos 协议 PTK(pass the key) #利用的 ekeys aes256 进行的渗透测试 lm加密算法是2003以前的老版&…

动画墙纸:将视频、网页、游戏、模拟器变成windows墙纸——Lively Wallpaper

文章目录 前言下载github地址&#xff1a;网盘 关于VideoWebpagesYoutube和流媒体ShadersGIFs游戏和应用程序& more:Performance:多监视器支持&#xff1a;完结 前言 Lively Wallpaper是一款开源的视频壁纸桌面软件&#xff0c;类似 Wallpaper Engine&#xff0c;兼容 Wal…

按照故障码类型分类的API接口

随着汽车的普及&#xff0c;车辆故障也成为了一个不可忽视的问题。对于车主来说&#xff0c;及时了解故障码的含义以及解决方案十分重要。挖数据平台为解决这一问题&#xff0c;提供了一套按照故障码类型分类的API接口&#xff0c;用于查询车辆故障、故障码适用品牌以及提供相应…

当 Redis 遇上 Serverless

亚马逊云科技开发者社区为开发者们提供全球的开发技术资源。这里有技术文档、开发案例、技术专栏、培训视频、活动与竞赛等。帮助中国开发者对接世界最前沿技术&#xff0c;观点&#xff0c;和项目&#xff0c;并将中国优秀开发者或技术推荐给全球云社区。如果你还没有关注/收藏…

杂文月刊投稿方式论文发表要求

《杂文月刊》是由国家新闻出版总署批准的正规文学类期刊。主要内容取向&#xff1a;杂文、散文、小说、诗歌、漫画、文学评论、艺术评论、戏剧文化、地方文化、非遗文化、美学艺术、教育等历史、文化、文学、艺术类的文章。是广大专家、学者、教师、学子发表论文、交流信息的重…

docker 在线安装mysql 8.0.21版本

1、拉取mysql 8.0.21版本镜像 2、查看镜像 docker images 3、在宿主机 /usr/local/mysql 下的 conf 文件夹下&#xff0c;创建 my.cnf 文件&#xff0c;并编辑内容 [mysql] default-character-setutf8 [client] port3306 default-character-setutf8 [mysqld] port3306 se…

Win10取消开机密码

1、首先确认你的 Windows 系统帐户中添加了密码。您可以在设置 - 帐户 - 登录选项中查看电脑是否有添加本机密码。 2、按 WinR 打开运行窗口&#xff0c;在窗口中输入 netplwiz 并按确定。 3、在弹出的用户帐户控制中&#xff0c;我们可以看到当前已添加密码的帐户。把要使用本…

可拖拽流程图组件开发

效果 说在前面 流程图在技术领域是一种常见的可视化工具&#xff0c;用于展示系统、应用或业务流程的各个步骤以及它们之间的关系。它们可以帮助开发人员和项目团队更好地理解和规划复杂的流程&#xff0c;从而提高工作效率和准确性。但是&#xff0c;传统的静态流程图有时无法…

【Vulnhub 靶场】【Looz: 1】【简单】【20210802】

1、环境介绍 靶场介绍&#xff1a;https://www.vulnhub.com/entry/looz-1,732/ 靶场下载&#xff1a;https://download.vulnhub.com/looz/Looz.zip 靶场难度&#xff1a;简单 发布日期&#xff1a;2021年08月02日 文件大小&#xff1a;2.1 GB 靶场作者&#xff1a;mhz_cyber &…