嵌入式系统开发-麦子学院(5)——linux高级编程之文件IO管理

linux高级编程之文件IO管理

接上篇文章:嵌入式系统开发-麦子学院(4)——Linux C初级编程2

1. 文件IO

linux 系统中,文件IO的流程,如下图所示。
嵌入式系统开发-麦子学院(5)——linux高级编程之文件IO管理_第1张图片
文件IO有5个函数:open() read(),write(),close(),leek()

1.1 open - 打开或创建一个文件*

open(char*,flag,mode)在fcntl.h库文件中声明。
函数作用:创建或打开某个文件。

参数 描述
char* 包含文件名和路径
flag 打开文件的方式
mode 创建文件的权限

flag的选项有:

flag选项 功能
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_CREAT 创建一个文件
O_EXCL 检测文件是否存在
O_TRUNC 打开文件覆盖
O_APPEND 打开文件追加

创建文件的权限:mode &(~umask)

返回值:

成功 文件描述符,文件的ID号——inode
出错 -1

1.2 close - 关闭一个文件inode

close(int inode)。

例子:touch命令的实现

#include "stdio.h"
#include "unistd.h"
#include "fcntl.h"
int main()
{
	int fd;
	fd = open(argv[1],O_CREAT|O_RDWR,0777);
	if(fd<0)
	{
		printf("creat file %s failure\n",argv[1]);
		return -1;
	}
	printf("create file %s sucess\n",fd = %d\n",argv[1],fd);
	close(fd);
	return 0 ;
}

1.3 write -写数据到一个文件

write(int fd,void *buf,size_t count)。在fcntl.h库文件中声明。

参数 描述
int fd 当前文件的文件inode
void *buif 写的内容buf
size_t count 写多少个字节

返回值:实际写的字节数

1.4 read -读取一个文件的数据

read(int fd,void *buf,size_t count)

参数 描述
int fd 当前文件的文件inode
void *buif 读的内容buf
size_t count 读多少个字节

返回值:实际读的字节数

1.5 leek-读取一个文件的位置指针

leek(int fd,off_t offset,int whence)。在sys/types.h unistd.h库文件中声明。

作用:调整读写的位置指针。

参数 描述
int fd 当前文件的文件inode
off_t offfset 偏移量,每读写操作所移动的距离,单位是字节的数量。可正负
int whence 当前位置的基点,有三个标志: ①SEEK_SET(文件的开头),②SEEK_CUR(文件指针的当前位置,③SEEK_END(文件的结尾)

返回值:

成功 文件指针的当前位置
出错 -1

例子:cp命令的实现

#include 
#include 
#include 
#include 	
int  main (int argc, char *argv[])
{
	int  rd_fd,wr_fd;
	char read_buf[128] = {0};
	char write_buf[128] = {0};
	int rd_ret = 0;
	
	if(argc <3)
	{
		printf("please input src file and des file \n");
		return -1;
	}
		
	rd_fd = open(argv[1],O_RDONLY);
	if(rd_fd < 0 )
	{
		printf("open src file %s failure\n",argv[1])
		return -2;
	}
	wr_fd =  open (argv[2],O_WRONLY);
	if(wr_fd <0)
	{
		printf("open des file %s failure\n",argv[2])
		return -3;
	}
	
	while(1)
	{
	 rd_ret = read(rd_fd,read_buf,128);
	 if(rd_ret < 128)
	 	break;
	 write(wr_rd,read_buf,rd_ret);
	 memset(wr_fd,read_buf,re_ret);
	}
	write(wr_rd,read_buf,rd_ret);

	close(rd_fd);	
	close(wr_fd);	
}

2.标准IO

标准IO与文件IO的区别:

文件IO 直接调用内核提供的系统调用函数,头文件是unistd.h
标准IO 是间接调用系统调用函数,头文件是:stdio.h

标准IO的实质还是通过C库函数去调用文件IO。

标准IO函数
文件打开关闭 fopen fclose
文件读写 fread fwrite
从文件中读取/输出字符串 fgets fputs
获取、输出字符串 gets puts
从文件中获取、输出字符 fgetc fputc
终端输出输入一个字符 getc putc
输出输入一个字符 getchar putcahr
格式化输入输出、从文件 fscanf fprintf
从字符串 sscanf sprintf
从终端 scanf printf
冲刷缓存区(全缓冲、含缓冲) fflush
光标定位 fseek ftell rewind
文件末尾 feof

标准IO缓存机制:① 用户缓存 ② c库缓存 ③内核缓存

嵌入式系统开发-麦子学院(5)——linux高级编程之文件IO管理_第2张图片

库缓存

1)全缓冲 :全缓冲指的是系统在填满标准IO缓冲区之后才进行实际的IO操作;注意,对于驻留在磁盘上的文件来说通常是由标准IO库实施全缓冲。

读:fread  写:fwrite

2)行缓冲 :在这种情况下,标准IO在输入和输出中遇到换行符时执行IO操作;注意,当流涉及终端的时候,通常使用的是行缓冲。

遇到换行符(\n)或写满缓存时,调用系统调用函数  stdout 
	读:fgets ,gets,printf,fprintf,sprintf
	写:fputs,puts,scanf

3)无缓冲 :无缓冲指的是标准IO库不对字符进行缓冲存储;注意,标准出错流stderr通常是无缓冲的。

无缓存 stderr

1.文件的打开 fopen()

    头文件:#include 
    函数原型:
    FILE *fopen(const char *path, const char *mode);
    返回值: 成功  返回FILE * 类型的指针指向你要打开文件
             失败  返回NULL         
    
    函数参数:const char *path  ---->你要打开文件的位置 
              const char *mode  ----》文件权限
                        r     以只读的方式打开文件
                        r+    以可读可写的方式打开文件
                        w     以只写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
                        w+    以可读可写的方式打开文件,如果文件存在就清空,如果文件不存在就创建
                        a     追加,如果文件不存在就新建 
                        a+    以读取和追加(文件末尾的写入),如果文件不存在,则创建它。

2.文件的读写 fread() fwrite()

       头文件:#include 
       函数原型
       size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
       返回值: 成功 返回读取到完整的数据块的个数
                失败 返回0或者小于的数
                判断文件是否读完不要在用返回值判断,新方式feof()判断
                
	       函数参数:void *ptr     ----》存储空间名
	                 size_t size   ----》每一个数据块的大小 字节
	                 size_t nmemb  ----》打算读取多少个数据块
	                 FILE *stream  ----》文件类型的FELE *的文件指针
	       
	       size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);

3.文件的关闭 fclose()

       头文件:#include 
       函数原型:
       int fclose(FILE *fp);
       返回值: 成功 返回0
                失败 返回feof()监测
                
        函数参数:FILE *fp  文件描述符

4.判断文件的结束标志 feof()

  头文件:#include 
  函数原型:
       int feof(FILE *stream);
       返回值: 不等于0  ---》文件读取完毕
                等于0    ---》文件没有读取完毕

5.设置文件的读写偏移 fseek()

 #include 
       int fseek(FILE *stream, long offset, int whence);
         返回值:成功 返回0
                 失败 返回-1  
                注意:lseek返回值和fseek()返回值意思不一样
                
         参数:FILE *stream  FILE * 文件
               long offset   偏移量
               int whence    偏移的位置
                    SEEK_SET  文件的开头
                    SEEK_CUR  当前的位置
                    SEEK_END  文件的末尾   
            例子:fseek(filep1,0,SEEK_SET);
       long ftell(FILE *stream);
         返回值:成功 返回文件当前位置距离文件开头的字节数
                 失败 返回-1
            例子:long ftell(filep1);相当于fseek(filep1,0,SEEK_END);
         
       void rewind(FILE *stream);//没有返回值
            例子:void rewind(filp1)//等价于fseek(filep1,0,SEEK_SET)
              将文件的偏移设置为起始位置

6.获取文件属性 fstat()

    头文件:#include 

       int fstat(int fildes, struct stat *buf);
       返回值:成功  返回0
               失败  返回-1
        参数:int fildes       你要获取属性的那个文件的文件描述符
              struct stat *buf 存放你获取到的文件属性 

7.fprintf() fscanf() sprintf() sscanf()

 标准输入      stdin
 标准输出      stdout
 标准错误输出  stderr
 
      可变参的函数(变参函数)
 #include 
       1) int fprintf(FILE *stream, const char *format, ...);
           参数:FILE *stream        FILE *  文件名
                 const char *format  字符串
                 ...
            例子:fprintf(filep,"hello%s%d%.2f\n",buf,year,d);
               //文件内容拼接
		2) int sprintf(char *str, const char *format, ...);
           //按照你指定的格式拼接字符串,比strcat要厉害
           参数:char *str           字符串拼接指定位置
                 const char *format  字符串格式
                 ... 
            例子:sprintf(buf0,"%sworld-%d-%d-%d",buf,year,month,day);
		3)  int fscanf(FILE *stream, const char *format, ...);
            参数:FILE *stream        FILE *  文件名
                  const char *format  字符串
                  ...
            往文件里面添加内容
		4) int sscanf(const char *str, const char *format, ...);
            //按照你指定的格式拆分字符串
            参数:char *str           字符串拆分指定位置
                 const char *format   字符串格式
                 ... 
            例子:sscanf(time,"%d-%d-%d",&year,&month,&day);//访问的是地址 &

8.fputs() fgets() fputc() fgetc() puts() gets() putchar() getchar()

   #include 

   int fgetc(FILE *stream);//从文件中读取一个字符 fread(buf,1,1,stream);
           返回值:你读取到的那个字符的ASCII码
   int getc(FILE *stream);//从文件当中读取一个字符
           返回值:你读取到的那个字符的ASCII码
   char *fgets(char *s, int size, FILE *stream);
         //从文件读取size个字节的数据放到指针s中
         返回值:返回读到的字符串的首地址  指针
          fgets(buf,100,stdin);//获取键盘输入
   int getchar(void);
         //监测缓冲区的回车字符
         while(getchar()!='\n')         
   char *gets(char *s);  gets(buf);
         //默认获取键盘输入的字符串

 #include 

   int fputc(int c, FILE *stream);//往文件中写入一个字符  fwrite
   
   int putc(int c, FILE *stream);//往文件中写入一个字符  fwrite

   int fputs(const char *s, FILE *stream);//相当于打印
            fputs(buf,stdout);
   int putchar(int c);  //打印字符
            putchar(a)==putchar(97)
   int puts(const char *s);//打印字符串  puts(buf);

目录IO

1.1目录的打开 opendir()

   头文件#include 
         #include 
   函数原型:
   DIR *opendir(const char *name);
   返回值:成功 返回DIR类型的指针指向你打开的目录
           失败 返回NULL
           
        参数:const char *name 完整的目录路径   

1.2 目录的读取 readdir()

   #include 

   struct dirent *readdir(DIR *dirp);
          返回值:struct dirent 目录结构体指针
          
    struct dirent {
           ino_t          d_ino;       /* 节点编号*/
           off_t          d_off;       /* 目录的下一个偏移位置 */
           unsigned short d_reclen;    /* 目录大小*/
           unsigned char  d_type;      /* 目录类型*/
           char           d_name[256]; /* 目录名字 */
       };//存放的是目录当中的每个文件的相关信息
文件类型判断
   DT_BLK      This is a block device. //块设备文件

   DT_CHR      This is a character device.//字符设备文件

   DT_DIR      This is a directory.//目录文件

   DT_FIFO     This is a named pipe (FIFO).//管道文件

   DT_LNK      This is a symbolic link.//软连接文件

   DT_REG      This is a regular file.//普通问价

   DT_SOCK     This is a UNIX domain socket.//套接字文件
   
   DT_UNKNOWN  The file type is unknown.//不认识类型

1.3新建目录 mkdir

    #include 
   函数原型:
   int mkdir(const char *path, mode_t mode);
    参数:const char *path  ----》你要建立的目录的路径
              mode_t mode      ----》新建文件的权限 0777
           
  1.4关闭目录 closedir()
    #include 

   #include 

   int closedir(DIR *dirp);//结构体指针

你可能感兴趣的:(嵌入式——麦子学院(学习路线))