Linux
一切皆文件
概念上来说,Linux中的所有资源,都可以通过文件的方式来进行访问和管理。
- 普通文件:包含数据的文件,可以是文本文件、二进制文件、脚本文件等。
- 目录文件:包含本文件和子目录文件名;本目录和子目录对应的inode号。
- 设备文件:代表硬件设备的文件,分为字符设备和块设备。设备文件通常位于 /dev 目录下,通过读写这些文件来与硬件设备进行交互。
• 字符设备:如键盘、串口等,数据以字符流方式处理。
• 块设备:如硬盘、光驱等,数据以块方式处理。 - 符号链接(软链接):指向另一个文件或目录的文件,包含目标路径的字符串,使用时,通过路径找到相应的inode块,再拿inode块中的地址。
- 硬链接:指向某一个inode块,inode块的指向可以随意修改
- 管道文件:用于进程间通信的文件,分为命名管道和匿名管道。命名管道文件通常位于 /tmp 目录下,通过管道文件,进程可以进行数据交换。
- 套接字文件:用于网络通信的文件,通常位于 /tmp 目录下,通过套接字文件,进程可以进行网络数据交换。
包管理工具apt
同mac的homebrew,通俗的说就是用命令行的360软件管家
homebrew的镜像源默认在github上,访问速度时快时慢
Vi工具使用
环境变量的设置
三种设置方式
Gitee的使用
由于之前基本都是在macOS+git+github,设置git的hook等操作。本次将会尝试国内很多人可能会使用的Windows+git+gitee的情况。不过gitee部署pages要上传身份证。。。就不弄pages了。
1、下载git
直接百度下?不好,骇客一点,使用Windows的命令行中的包管理工具winget下git
1 | winget seach git |
我丢,骇客个屁,设置环境变量,没有能在命令行下的编辑器,还得下。。直接图形界面搜索环境变量一改
2、搞一个公钥
一般会生成在用户的.ssh文件夹下
1 | ssh-keygen -t rsa -b 4096 -C "example@example.com" |
粘贴到Gitee去
3、创建本地git,初始化,绑定,提交
在一个dir下,进行
1 | # 初始化 |
4、熟悉一下git可能遇到的情况和应对操作
一、获得公司项目仓库代码 : clone
二、将仓库新的更改拉取到本地版本库的远程分支 : fetch
1 | # fetch后使用branch -a查看所有分支状态 |
三、查看更新了什么东西,确定是否需要合并到本地
1 | git log master..origin/master |
四、合并到本地 : merge
二四步也可以用pull直接合并,使用前保证工作区、暂存区、本地分支应当内容同步。merge和pull不会覆盖本地其他内容,只会补充没有的内容
1 | # 先将活动分支设为需要合并的分支,假设为master |
五、修改分支上的版本:reset
1 |
|
六、工作区删错文件需要从暂存区或版本库拿回:checkout
1 |
|
交叉编译环境
尝试在服务器端配置交叉编译环境,和物理机操作一样,安装即可
本次尝试在mac M1 端配置交叉编译环境看看是否可行
1 | brew tap ArmMbed/homebrew-formulae #添加arm源 |
tftp匿名传输协议
Mac OS
尝试使用mac M1 端自带的tftp
找到tftp文件夹,将需要上传的文件放入
1 | cd /private/tftpboot |
在开发版上:
1 | tftp -g -r fileName macIP |
即可获得mac上的文件
但是在使用
tftp -p -r fileName macIP时却显示失败。原因是mac M1下的tftp.plist配置文件没有打开tftp接收。需要修改配置文件,但是这个配置文件连root用户都不能修改。一说是要让电脑进入安全模式禁用SIP,但是我禁用了还是没有权限啊。因此在mac M1上暂时无法解决tftp获取开发版上文件的方法。。有大神会吗求求
Windows
Windows当然是图形窗口好用,直接去下一个tftp图形界面就可以,put和get都可以完美使用
SCP文件传输协议
1 | # 本地文件复制发送到远端 |
文件的读写
光标指针
无论使用哪一个IO,同一个文件描述符或FILE都共享同一个文件光标。
也就是说,只要文件描述符相同,同时读写将会出现不确定行为,因为光标在两个函数的操作下同时移动
##使用系统IO(初级)文件读写 open close write read lseek
所有的读写操作都直接通过文件描述符进行,进入内核空间
劣势:代码复杂,特别是在处理结构化数据时。错误处理机制不如标准IO。没有缓冲机制,会比较消耗资源
优势:更底层,可以精准控制和精细操作
具体可以man 2 函数名
需要注意的点
- 文件读写将会有一个文件指针,即光标。光标可以理解为一个指针,文件在操作时光标会随之偏移。在初级的文件IO中用户可以使用lseek和文件描述符来控制这个指针。
- 在给main函数传递参数时,argv[0]是默认留给命令行第一个字符串的,因此文件名应该从argv[1]开始
- 使用缓冲区时,常常需要将缓冲区清零。创建时:char buf[10]={0}; 一般时:memset(buf,’\0’,10);
使用标准IO(进阶)文件读写 fopen fclose fread fwrite fleek
标准IO更为常用,因此对标准io的使用应该非常熟悉
fread(缓冲区指针buff,size4,nmemb3,FILE * stream);
比如文件中有10个字符
按4个字符的单位来读,读3次。返回值是读4个的次数。如果某一次发现不够4个字符,就读剩余的,且设置文件流结束标志EOF,且本次不算一次完整读写。因此返回值为3.
fwrite(缓冲区指针buff,size4,nmemb3,FILE * stream);
发现不够4个字符时,函数也会继续读满4个包括后面未定义在内的字符,将其强制写入文件流。可能会导致文件成为二进制文件。
也就是说没有其它错误的情况下,即便buff值不够,也会正确返回nmenb3?????????????好像不是,但是编译器确实给我返回了3
1 | //fwrite函数写入未定义字符到文件,会发生什么?是否会算一次完整的写入? |
大佬帮我看看,万分感谢
ferror、feof、perror和clearerr
优秀的错误处理机制也是标准IO的优势,必须用
perror(参数)会获取最近一次发生错误的错误信息,打印在参数后面。因此常用在类似fp == NULL的条件下打印具体错误信息
ferror(fp)会判断fp的错误并且返回非零值,因此适合作为可能出错的地方的if的判断值,一般配合perror使用。例如
1 | 写文件代码; |
feof(fd) 返回文件是否有结束标志,常用于fread和fget等函数,当文件流结束时,置非零数
1 | FILE *fp = fopen("example.txt", "r"); |
clearerr,当有可能出现错误时,我们需要重新打开文件,此时,我们应该清楚文件流的错误和文件流结束标志。使用clearerr(fp);或者使用rewind(fp);可以将文件光标移动到文件的开头且cleareer(fp);
手写copy函数:
1 | //使用标准IO,实现文件拷贝功能。 |
使用常用标准输入输出库函数方便地构建和读取格式化数据
文件的属性
stat fstat istat
我们man 2 stat可以看到stat函数以及结构体stat的内容。从stat
设备号 stat.st_dev
每个文件都会有设备号,一般的文件会归属于一个设备,比如在桌面上创建一个文件,这个文件就归属于硬盘设备,stat.st_dev可以获得文件所属的的设备的设备号,也就是文件系统的设备号
特殊的文件自己会有一个设备号,例如块设备,字符设备。比如说一个键盘,那么我们可以通过stat.st_rdev获取设备号
其次,设备号又分为主设备号和次设备号,通过major和minor函数获取。
主设备号规范了设备类型,次设备号即序号,类似前面的fd
1 | void print_dev_no(char* dev_name) { |
类型与权限 stat.st_mode
stat.st_mode是一个16位二进制数
通过宏定义可以拿到文件类型



