当前位置: 首页 > ai >正文

Linux应用(1)——文件IO

一、简介

1.1文件属性

Linux下文件共有'bcd-lsp'七个属性类型
b: block 块设备 (储存设备) 驱动开发中用到的文件属性
c: char 字符设备 驱动开发中用到的文件属性(lcd屏 定时器 通信接口)
d : 目录
- : 普通文  .c .s  .txt .doc ....
l : link 链接文件-- 数据库开发中
s : socket  套件字文件---网络编程开发中
p: pipe  管道文件----进程通信开发中

相对路径:从Linux最初,根路径开始的路径
相对路径:以某一级路径作为参考

1.2Linux平台命令操作

第一类:系统命令
Linux系统把常规要用到的功能已经编写好C代码,并固定编译生成了固定的可执行文件名,全部都存放在linux根目录下 bin 的文件中, 用户直接调取即可
第二类:用户自定义命令
用户自己编写C代码,编译生成可执行文件,运行可执行文件
---用户生成的可执行文件名 是 自定义的

1.2.1 命令格式

  1. 命令的执行: 在终端上命令, 回车运行
  2. 终端上一行也可以输入多个命令 使用 ; 隔开,但通常一个命令一行
  3. 存在几种命令查找方式
    方式1:通过命令查询手册
    方式2:可以直接在linux下终端上通过命令名 --help

    方式3:可以直接在linux终端下通过man命令,这是一种英文查找方式, 包含所有的命令

  4. 命令的格式
    命令提示符(命令名)     [选项]   <参数/文件>
    解释说明:
    [ ] 都是选项,可有可无,< > 或无括号,必须要添加的

1.3常用的系统命令使用方式

用户常见的系统命令分成四类:
第一类:和系统运行相关的
echo >  >>   *   pwd  cd  alias  grep  cal  date  chmod
第二类:和文件相关的
touch  rm  cp  mv  cat   gedit  gcc  g++
第三类:和文件夹(目录)相关的
mkdir  rmdir   cp  mv  ls  tar
第四类: 和用户使用相关的
useradd  su  sudo  passwd   userdel

二、基础命令

2.1与系统相关

1.echo
把echo 空格后的内容 原样显示在终端上

注意事项:
要输出的内容 是否使用 “” 引起来 都可以,效果是一样的, “” 不会输出
如果要想显示” 需要使用 转义字符 \”  

命令2: >     >>
一般都是和echo 命令配置使用; 输出重定向
命令格式:把要显示的内容存放到文件中
echo  要显示的内容  > 文件名
echo  要显示的内容  >> 文件名
注意事项:
文件如果 不存在 , 就会先自动创建文件再写入
文件如果 存在 :
>     以覆盖方式写入       
>>     以追加方式写入

命令3:alias   unalias
命令功能:给命令起别名  删除命令别名
--主要针对一些比较长的系统命令
使用方式1: alias   查找系统下以存在的别名

使用方式2:给命令起别名
格式  alias  别名=’命令原名’      
注意 是一对单引号’’

命令4:  *
命令5: pwd
命令6: cd

命令7: cal
显示日历功能
命令格式1: cal      显示当前月份的日历
命令格式2: cal  年份      显示指定年份所有月份的日历
命令格式3: cal 月份 年份  显示指定月份的日历
命令8: date
显示当前时间

命令9: chmod

2.2与文件相关

新建touch、删除rm、编写 gedit 、编译 gcc 、运行、查看cat、复制cp 、剪切mv

1.用一条指令在桌面上创建1.c 2.c 3.c 4.txt 5.txt 6.txt共计六个文件

2.用一条指令实现:在桌面上创建一个名为test_dir的目录文件,在该目录中创建名为a1的目录文件,在a1中创建名为b2的目录文件
使用  mkdir  -p   递归创建目录

  mkdir  -p 

3.用一条指令实现:删除桌面上文件夹test_dir,要求删除时有提示(默认延续1.3.2执行)
以询问方式删除非空目录  rm  -ir

rm  -ir

4.结合通配符,用一条指令实现:删除桌面上所有的以.c结尾的文件

rm *.c

5.在桌面上的C_code/0708/ 目录下新建源文件,编写代码实现
步骤1:在linux桌面开一个终端
步骤2: mkdir -p C_code/0708/    递归创建文件夹
步骤3:cd   C_code/0708/    跳转到文件夹下
步骤4: 新建编写文件   gedit  hello.c
步骤5: 编译源文件   gcc  hello.c  -o  hello
步骤6: 运行可执行文件    ./hello

6.使用ls -l,分析目标文件的类型和权限问题

7.如何创建一个名为 test.txt 的空文件,并设置其权限为 rw-r--r--(644)
步骤1: touch  test.txt
步骤2: chmod   0644(八进制) test.txt

8.如何将 /home/user/data 目录压缩为 data.tar.gz
步骤1:保证  /home/user/data   存在 
mkdir  -p  /home/user/data
步骤2:在压缩   tar  -czvf  data.tar.gz     /home/user/data

三、文件操作

3.1简介

Linux系统输入输出的对象为应用层 驱动层(内核)
以应用层为中心,
input输入:数据从驱动层/文件进入应用层
output输出:数据从应用层到驱动层/文件
Linux文件下存在多种io相关api函数
读函数:就是输入
写函数:就是输出

3.2 分类

分类方式一:按照文件属性
第一类:特殊文件
只有三个: 标准输入(键盘)、标准输出(屏幕)、标准错误
第二类:普通文件: .c  .txt   .h  .s   .sh 等等

分类方式二:按照API函数特性
第一类: 文件io,内核提供的系统调用,直接操作文件描述符(fd)
第二类: 标准io,C 库(glibc)在用户空间实现的带缓冲的流式 I/O,用 FILE *
第三类: 目录io ,门用来遍历/读取/创建/删除目录的一组函数,同样基于文件描述符或 FILE *,但接口与普通文件不同

3.3文件操作注意事项

  1. 文件操作的方向及对应要调取的API函数
  2. 采用文件可以做特殊文件操作,也可以对普通文件操作
    对特殊文件的操作:是可以直接读写的
    对普通文件的操作:需先打开文件,然后再操作
  3. 文件指针的偏移特性,需要考虑是应用还是要避开
3.4文件io特性
  1. 文件IO可以对普通文件操作,也可以对特殊文件操作
  2. 文件会存在文件指针,当open打开文件时,文件指针默认在文件开始处,对文件的读写,都会造成文件指针的偏移(以字节为单位),当close关闭后,文件指针默认在文件末尾
  3. 文件IO的读写函数没有缓冲区,读写是马上生效的,是一种低速IO
  4. read 输入--> 文件数据的读取
  5. write 输出--->数据存放到文件

特殊文件

文件IO--文件描述符

标准IO--文件流指针

标准输入

0

stdin

标准输出

1

stdout

标准错误

2

stderr

普通文件

默认从3开始分配

四、文件函数

4.1 open函数

头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型:
int open( const char * pathname, int flags);
int open( const char * pathname,int flags, mode_t mode);
函数参数:
@param1
const char * pathname: 带路径的文件名    "/home/save.txt"
@param2
int flags  : 可以进行按位或 一起的 文件指定打开方式
O_RDONLY  :  只读    O_WRONLY : 只写    O_RDWR : 可读可写
O_CREAT     :如果文件存在,就直接打开;如果文件不存在,就创建并打开
O_EXCL       : 如果文件存在,就直接打开;如果文件不存在,就报错,结束函数
O_TRUNC    :   以 覆盖方式打开文件
O_APPEDN  :   以追加方式打开文件
O_RDWR | O_CREAT | O_TRUNC  : 以覆盖的方式打开一个可读可写的文件,如果文件存在,就直接打开;如果文件不存在,就创建并打开
@param3
mode_t mode: 文件掩码--一个八进制数据(和chmod修改权限命令参数一样),表示文件本身具备什么权限,该参数通常和 O_CREAT 组合应用;也即是说,如果flags参数中存在 O_CREAT,那就填充参数3;如果flags参数中没有O_CREAT,那就不需要参数3
函数返回值:
int   文件描述符 (文件ID),后续通过 文件描述符 对文件进行操
<0: 打开失败     
>0: 打开成功-默认从3开始分配
函数功能:
对同一个文件可以多次打开,文件描述符依次递增;
可以利用对同个文件的多次打开,实现把文件指针偏移到文件开始处;同样也可以利用lseek函数实现

4.2 close函数

头文件:#include <unistd.h>
函数原型:
int  close(int fd)
函数参数:
@param1
int  fd  打开文件的文件描述符
函数返回值:
int 是否关闭成功--通常不用
函数功能:用来关闭文件
函数特性:
文件关闭后, fd 文件描述符就会被系统回收

4.3 read函数

头文件:
#include<unistd.h>
函数原型:
ssize_t read(int fd,void * buf ,size_t count);
函数参数:
@param1
int  fd:  文件描述符--表明要对哪个文件操作
@param2
void * buf:  应用层接收  buff
@param3
size_t count:  一次从文件中读取的字节数
函数返回值:
ssize_t  :实际从文件中读取的字节数,通常会作为文件是否结束(尾部)的判断依据
函数功能:一次从fd文件 中读取count字节到buf中
读函数--输入---数据从文件进入应用层(内存buf中)----数据的取操作
函数特性:
读操作同样会改变文件指针的偏移
char buf[20];
scanf("%s",buf); 等价于   read(0,buf,20);

4.4 write函数

头文件:
#include<unistd.h>
函数原型:
ssize_t write (int fd,const void * buf,size_t count);
函数参数:
@param1
int fd: 文件描述符--要写到哪个文件中
@param2
const void * buf:要写入的数据
@param3
size_t count:  要写入的字节数
函数返回值:
ssize_t  实际写入的字节数--应用不多
函数功能:
把内存buf中count字节写入到fd文件中
写函数--输出--数据从应用层(内存buf)写到文件中--数据的存操作
函数特性:
1.写操作同样会改变文件指针的偏移
printf("hello\n"); 等价于 write (1,"hello\n",7);

4.5 Iseek函数

头文件
#include<sys/types.h>
#include<unistd.h>
函数原型:
off_t lseek(int fildes,off_t offset ,int whence);
函数参数:
@param1
int fildes: fd  文件描述符--要调整哪个文件
@param2
off_t offset: 偏移量--单位   字节;>0,往右偏移;<0,往左偏移
@param3
int whence: 参考位置--文件指针从哪个位置开始
系统提供了三个参考位置宏表示
SEEK_SET    :  文件开始处
SEEK_CUR  :     文件当前处
SEEK_END :      文件尾部
lseek(fd,0 ,SEEK_SET);// 实际上就是文件开始处
函数返回值:
是否偏移成功--使用不多
函数功能:
把fd文件的文件指针从whence开始偏移offset
调整文件指针的位置
函数特性---重新调整文件指针的位置

---用户就需要考虑什么场景使用???--因为读写改变文件指针的位置是一种默认特性

常用于需要重新调整文件指针的场景
场景1: 信息的查找--每次都是从头开始
场景2;   函数中多次对同一个文件读写操作

4.6 练习

/*2.首先新建一个文件  比如 1.txt  写入一串任意字符串  比如: "sdg23542sdgfDSAsGA",编写一个函数,读取1.txt文件内容,一次读取4个字节,查找指定字符串。是否出现和出现的次数: 比如 "sdgf"*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{int fd                     ;//定义文件描述符char buf[4]={0}            ;//定义接收数组int num                    ;int count=0                ;//次数fd=open("./1.txt",O_RDONLY);//以只读的方式打开文件if(fd<0)                    //打开失败{printf("open error\n")   ;return -1                ;}printf("fd=%d\n",fd)       ;//输出文件描述符while(1){num= read(fd,buf,4)       ;//读取fd对应文件中四个字节到buf,并返回实际读到的字节数if(num==4){if(strncmp(buf,"sdgf",4)==0){count++              ;memset(buf,0,4)      ;//将4个0写入到buf中}}else if(num<4)break                   ;}printf("共出现了%d次",count);return 0                   ;
}
/*编写一个函数, 从键盘得到3个数据信息,写入到 2.txt文件中,其中每个信息占用2.txt中的一行*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main()
{int fd;char buf[20];//用于接收fd=open("./2.txt",O_RDWR | O_CREAT | O_TRUNC,0644);// 以覆盖的方式打开一个可读可写的文件,若文件不存在,则创建后打开if(fd<0){write(1,"open error\n",11);//往标准输出中写入return -1;}printf("fd=%d",fd);for(int i=0;i<3;i++){printf("请键盘输入第%d行\n",i+1);scanf("%s",buf);strcat(buf,"\n");write(fd,buf,strlen(buf));}return 0;
}
/*用文件io实现 往 4.txt文件中写入3行数据,并读取文件中的数据显示*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main()
{int fd;char buf[20];//用于接收char revbuf[20];fd=open("./4.txt",O_RDWR | O_CREAT | O_TRUNC,0644);// 以覆盖的方式打开一个可读可写的文件,若文件不存在,则创建后打开if(fd<0){write(1,"open error\n",11);//往标准输出中写入return -1;}printf("fd=%d",fd);for(int i=0;i<3;i++){printf("请键盘输入第%d行\n",i+1);scanf("%s",buf);strcat(buf,"\n");write(fd,buf,strlen(buf));}lseek(fd,0,SEEK_SET);//将文件指针偏移到最开始处read(fd,revbuf,50);printf("读到的数据为:\n%s",revbuf);return 0;
}
/*利用文件io实现  cp 拷问文件命令的重写  cp  1.c  2.c */
//运行格式 ./可执行命令 源文件 目标文件
//带参主函数 ./mycp 1.txt 2.txt
//int argc 终端运行时参数个数 
//char*argv[] 每一个参数
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>int main(int argc,char*argv[])
{int srcfd,objfd;//源文件,目标文件描述符char revbuf[20];int num,count=20;//num为实际读到的字节数,count为计划读到的字节数if(argc!=3){printf("请以%s srcfile objfile 形式运行\n",argv[0]);return -1;}//先打开源文件srcfd=open(argv[1],O_RDONLY|O_EXCL);//以只读的方式打开源文件,如果文件不存在,则报错返回
if(srcfd<0)
{printf("%s open error\n",argv[1]);return -1;
}
printf("srcfd=%d\n",srcfd);
//在打开目标文件objfd=open(argv[2],O_RDWR | O_CREAT | O_TRUNC,0644);//以可读可写覆盖的方式打开源文件,如果文件不存在,则创建文件
if(objfd<0)
{printf("%s open error\n",argv[2]);return -1;
}
printf("objfd=%d\n",objfd);
//开始读
while(1)
{num=read(srcfd,revbuf,count);//读源文件20个字节到revbufif(num==count){write(objfd,revbuf,num);}else{write(objfd,revbuf,num);break;}}return 0;
}

http://www.xdnf.cn/news/19799.html

相关文章:

  • 部署jenkins并基于ansible部署Discuz应用
  • 嵌入式|RTOS教学——FreeRTOS基础3:消息队列
  • Unity之Spine动画资源导入
  • 小游戏公司接单难?这几点原因与破局思路值得看看
  • 聚焦诊断管理(DM)的传输层设计、诊断服务器实现、事件与通信管理、生命周期与报告五大核心模块
  • RTSP流端口占用详解:TCP模式与UDP模式的对比
  • 面向深层语义分析的公理化NLP模型:理论可行性、关键技术与应用挑战
  • 大语言模型领域最新进展
  • 如何将JPG图片批量转为PDF?其实可用的方法有很多种
  • TC-2024《Fuzzy Clustering guided by Spectral Rotation and Scaling》
  • shell-awk命令详解(理论+实战)
  • 通过IDEA写一个服务端和一个客户端之间的交互
  • 解决通过南瑞加密网关传输文件和推送视频的失败的问题
  • PyTorch 面试题及详细答案120题(116-120)-- 综合应用与实践
  • 专项智能练习(音频基础)
  • 水泵运行组态监控系统御控物联网解决方案
  • 基于SpringBoot的旅游管理系统
  • 03 - HTML常用标签
  • Nano Banana 的 100 种用法 - AI 图像生成完整提示词宝典
  • 超低延迟RTSP播放器的技术挑战与跨平台实现之道
  • 【GitOps】Argo CD部署应用程序
  • 嵌入式|RTOS教学——FreeRTOS基础2:任务调度
  • 【mac】如何在 macOS 终端中高效查找文件:五种实用方法
  • 怀古感今慎独自省慎思
  • 中科米堆CASAIM自动化三维测量设备测量汽车零部件尺寸质量控制
  • 安全、计量、远程控制,多用途场景下的智慧型断路器
  • 超10公里远距离图传模块——开启无线影像传输新纪元
  • 写好 Prompt 的 12 条实践经验
  • 目标检测定位损失函数:Smooth L1 loss 、IOU loss及其变体
  • ReACT Agent概述