首先 看C语言的 文件IO
hello.c 读文件
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *fp =fopen("myfile","r");//打开文件myfile,得到一个指向文件的指针
if(!fp)
{
perror("fopen");
return 1;
}
char buff[1024];
const char* msg ="hello world !\n";
while(1)
{
ssize_t s =fread(buff,1,strlen(msg),fp);//从文件中读 strlen(msg)长度的数据 1代表读1 strlen字节
if(s > 0)
{
buff[s] = 0;
printf("%s",buff);
}
if(feof(fp))//fp指针走到文件尾了
break;
}
fclose(fp);//关闭流
return 0;
}
hello.c 写文件
#include <stdio.h>
#include <string.h>
int main()
{
FILE * fp =fopen("myfile","w");//给myfile文件写入
if(!fp)
perror("fopen");
const char* msg= "hello world !\n";
int count =5;
while(count--)
{
fwrite(msg,strlen(msg),1,fp);
printf("%s",msg);
}
fclose(fp);
return 0;
}
C 语言读写文件都要使用一个指向文件的指针fp;我们在创建这个时同时赋予了权限
fwrite 和 fread 都有4个参数。
C++读写文件
hello.cpp 写文件
#include <stdio.h>
#include <string.h>
//#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main()
{
umask(0);//将文件的默认权限置为0
int fd = open("myfile",O_WRONLY | O_CREAT ,0644);//创建一个myfile 文件 ,同时赋予权限 ,得到一个对应的文件描述符
if(fd < 0)
{
perror("open");
return 1;
}
else
{
int count =5;//循环5次康康
const char* msg = "hello JJ !\n";//这里放上\n可以zai write 的时候 自动换行
int len =strlen(msg);
while(count--)
{
int n = write(fd,msg,len);//fd 文件描述符, len 每次 期望 读取多少个字节,返回值为实际每次读取的字节数
printf(" 读取了%d 字节\n",n);
fflush(stdout);
}
}
close(fd);
return 0;
}
hello.cpp读文件
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{
int fd = open("myfile",O_RDONLY);
if(fd < 0)
{
perror("open");
return 1;
}
const char* msg = "hello JJ !\n";
char buff[1024];
//int count =5;
while(1)
{
ssize_t s =read(fd ,buff,strlen(msg));//给 buff 数组 缓冲区中读
if(s > 0)//读到就输出
{
printf("%s",buff);
}
else
{
break;
}
}
close(fd);
return 0;
}
我们发现 C++中
1 创建了一个fd文件描述符 ,在创建文件时赋予了权限0664,
2 读写方式也成为O_RDONLY和O_WTONLY 两种
3 read write 函数也只有3个参数。
接口介绍:
OPEN
1 头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
2
int open (const char* path , int flags);
int open(const char* path,int flags ,mode_t mode)
path: 路径名字符串 “”
flags:打开文件时需要传入的多个参数,可以包含权限 O_RDONLY O_WTONLY O_RDWT
上边三个权限 ,三选一
O_CREAT//文件不存在就创建,同时需要带上mode 权限
O_APPEND 追加写
open 函数
成功返回打开文件的 fd (文件描述符)
失败返回 -1;
文件描述符 fd
看了 open函数 ,我们都知道了,文件描述符fd是一个小整数。
0 & 1 & 2
分别代表 标准输入 、标准输出、 标准错误
Linux 进程默认这三个打开的文件描述符,他们分别对应 键盘、显示器、显示器
所以输入,输出还可以这样玩
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
int main ()
{
char buf[1024];//缓冲
ssize_t s;
while ((s=read(0,buf,sizeof(buf)) ) >0 )// 0 --> 标准输入
{
buf[s]=0;//收尾
write(1,buf,strlen(buf));//1 --> stdout
write(2,buf,strlen(buf));// 2---> stderr
}
return 0;
}
我们知道 ,文件描述符是一些小整数,当打开文件时,操作系统就会创建一些相应的文件描述符,描述目标文件,于是就有了 file 结构体,表示一个已打开的文件对象,在进程执行open函数时,必须让进程和文件联系起来**。每个进程都有一个 file指针,指向一张files_struct 这样的表,,而这些文件描述符就在file_struct中形成一个指针数组**,数组每个元素指向打开的文件指针,**所以 本质上,文件描述符就是数组的下表,**所以只要拿着文件描述符,就可以找到对应的文件。
2
文件输出重定向
当我们在代码中关闭了 close(1)标准输出之后,,结果发现文件描述符输出到myfile2文件中。
这就是重定向
经多多次调试测试 ,我发现 ,文件描述符丢失(close)规则:
1 **号(标准输出)丢失,那么凡是标准输出的内容都写到了文件中,
**
2 其他的文件描述符丢失,将创建 文件描述符排序最低的文件描述符
1 一般库函数写入文件 全缓冲,而写入显示器 是 行缓冲
2 printf, fwrite 库函数自带缓冲区,(进度条)
当发生重定向到文件就会发生
行缓冲 ————> 全缓冲
3 缓冲区中的数据不会被立即刷新,甚至在fork()之后,但是进程退出后,会统一刷新,写入到文件中
4 fork()的时候,父子进程都会发生写拷贝
5 printf fwrite 这两个库函数都自带缓冲区,而且是行缓冲, 而write没有自带缓冲区,。 另外 ,我们说的缓冲区都是用户级别的,是为了提高整体性能,而OS 也提供相关的内核级缓冲区,我们不去管那个。 而write系统调用函数没有缓冲区,那么说明 库函数 printf ,fwrite的缓冲区 就是由C标准库提供的。
常见的重定向还有 > >> <
函数 int dup2(int oldfd ,int newfd)
ls-l 命令 看到的结果:
ll 命令 包含7列
模式
硬连接数
所有者
同组者
大小
最后修改日期
文件名
硬连接:
我们看到的文件名不是真正的文件名,而是inode,在linux可以让多个文件对应一个inode。
eg :
touch abc
ln abc def
ls-1i abc def
1 我们发现 abc def 的 连接状态完全相同,他们被称为指向文件的硬连接 。内核记录了这个连接数inode 1044327258的连接数为2
2 删除文件时,底层分两步
1 连接数-1 ,等于0 时 释放对应的内存
2 在目录中将对应的记录删除。
Linux一切皆文件
文件类型并不以后缀区分
- : 普通文件
l : 链接文件(软链接 相当于快捷方式)
d ; 文件夹
p ;管道文件
s ;socket文件
b ; 块设备文件 eg 硬盘
c :字符设备文件 例如屏幕等串口设备
In -s 源文件 +创建的软链接名称
In 源文件 +创建的软链接名称
区别: 软链接没有自己的节点,相当于快捷方式
硬链接文件有自己的节点 。
touch ;更改文件时间属性
touch -d 使用指定时间刷新文件时间属性,不存在则创建
touch -r 已指定文件的时间 修改文件属性
cat 现实显示文件内容
打印到终端
cat -n 安行显示
tac 安行逆序打印文件内容
more 分页显示文件内容
空格 向下翻页,
b 向上翻页
less
/string 向下匹配字符串
?string 向上匹配字符串
head
head -n +文件
显示文件 头 n行内容
tail 相反
tail -n +文件
tail -f 一直刷新文件末尾的新数据
head tail 都默认显示十行
head +文件 | tail -n 1 ;显示文件的第十行内容
重定向:
>>改变数据流向 ,追加到文件末尾
> 改变数据流向,将原数据清空后再写入
tail -f 常用在查看日志中
压缩 解压缩
zip 压缩后的文件名+.zip 要压缩的文件名
Linux 下最常用gzip
gzip +文件名
压缩后 会将原文件删除
新文件 =原文件名+.gz
解压缩
gunzip +压缩包
bzip2/bunzip2 bzip2 文件压缩解压缩
注意 Linux 下 没有默认 rar压缩包的解压,windows下有 ,但Linux可以下载安装
tar 集合 打包解包
-c 打包
-v 详细信息
-f 指定打包/解包文件
-x 解包
打包解包过程不涉及压缩解压缩
想要同时 压缩解压缩
tar -zcvf package.txt a b c
tar -zxvf package.txt
不清楚压缩包格式 ,可以去掉z 他内部可以检测出来
grep
grep -R +‘查找的东西’ + 目录 会递归查找
grep -V 反向查找
find + 目录 ./ -name +" 要查找的字符串"
find ./ -name “a” /包含a的
find ./ -name “*a” 以a结尾的
find ./ -type +七种文件类型之一
find ./ -size + 大小 按文件大小查找
find ./ -szie +5k 文件大小大于 5k的
find ./ -size -5k 文件大小 5k 以内的
find ./ -mtime +1 按修改时间来找,以天为单位
find ./ -mmin +10 安修改时间查找 ,查找10分钟以上的
find
-name
-size
-mtime +/-n :按天查找
mtime 修改时间
ctime 状态改变时间
atime最后一次访问时间
-mmin -cmin -amin 按分钟查找
-type(7🀄️)
d
b
l
s
c
p
-
-exec :连接其他命令,对找到的文件进行处理
eg: find ./ -size +5k -exec rm ‘{ }’ \
对当前目录大于5K的文件进行查找并删除