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

嵌入式学习第十六天--stdio(二)

文件打开

open函数     

#include <fcntl.h>
int open(const char *pathname,int flags);
int open(const char *pathname,int flags,mode_t mode);
功能:
   打开或创建文件
   
参数:
  @pathname  //打开的文件名
  @flags     //操作的标志
             
             //必选
             O_RDONLY  //只读
             O_WRONLY  //只写 
             O_RDWR    //读写 
             
            //附加
            O_APPEND  //追加 
            O_CREAT   //文件不存在 创建 
            O_TRUNC   //文件存在  截短为0 
  @mode     一般不用
            当flags中使用了 O_CREAT 时,需要指定 mode   
            mode 0777
                 0666
                 0444                  
返回值:
  成功 文件描述符
  失败 -1 && errno会被设置 
  
  
fopen             open
r                 O_RDONLY 
r+               O_RDWR

w                O_WRONLY|O_CREAT|O_TRUNC 
w+              O_RDWR|O_CREAT|O_TRUNC

a                O_WRONLY|O_APPEND|O_CREAT
a+              O_RDWR |O_APPEND|O_CREAT

FILE * fopen(const char *pathname,const char *mode)
{
   ...
   if (strcmp("r",mode))
       open(pathname,O_RDONLY);
}


文件创建好后的权限:


  a.指定的mode 
  b.umask  (掩码) //二进制位 --- 遮住 

  最终文件的权限 = ~umask & mode
  
  0  7   7   7 
    111 111 111  mode
  0 000 000 010
    111 111 101 ~umask 
    ------------
    111 111 101 
     7  7   5
    

                        

库函数 和 系统调用         


close 关闭:


int close(int fd);
功能:
   关闭文件描述符
   以便 再次使用 
参数:
  @fd  要关闭的文件描述符
返回值:
  成功 0
  失败 -1 


  
文件描述符:


1.非负整型数值 
2.分配原则
  最小未使用   
3.范围 
  0~1023 
  
  
 


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

#include <unistd.h>
功能: 
    从fd中读数据 ,存到 buf中 
参数:
   @fd 要读取的文件 
   @buf 存放读取到的数据的 内存空间 
   @count 一次要读取的数量(字节)
返回值:
   成功 表示成功读到的字节数 
   失败 -1 && errno 
   


ssize_t write(int fd,const void *buf, size_t count);

#include <unistd.h>
功能: 
    把buf中 写到fd中 
参数:
   @fd    要写入的文件 
   @buf   存放数据的 内存空间 
   @count 一次要写入的数量(字节)
返回值:
   成功 表示成功写入的字节数 
   失败 -1 && errno 

缓存的设计


缓存 设计的目的提高效率  
本质上来说 ---缓存其实就是一块内存空间 

行缓冲:

1k, terminal,主要用于人机交互stdout
    
    缓存区满或者遇到\n刷新    1024
                行缓存多是关于终端的一些操作
                1.遇到\n刷新
                2.缓存区满刷新
                3.程序结束刷新
                4.fflush刷新  fflush(stdout);


                
全缓冲

4k,主要用于文件的读写
    缓存区满刷新缓存区 4096
            对普通文件进行标准IO操作,建立
            的缓存一般为全缓存
            刷新条件:
                1.缓存区满刷新
                2.程序结束刷新
                3.fflush来刷新  fflush(fp);


无缓冲

0k  主要用于出错处理信息的输出 stderr 
    不对数据缓存直接刷新
    printf();==>>stdout 
    fprintf(strerr,"fopen error %s",filename);
                界面交互    出错处理
使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。
缓冲区的大小是可以设置

linux下缓存设计:
交互 --- 行缓存 
文件 --- 全缓存 
出错 --- 不缓存 

./a.out < main.c   //< 表示输入重定向 
./a.out > main.c   //> 表示输出重定向 

fread/fwrite //二进制读写函数 按对象读写

#include <stdio.h>
size_t  fread(      void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
     二进制流的读/写
参数:
   @ptr   表示存放数据的空间的地址 
   @size  要操作的单个元素(对象)的大小
   @nmemb 要操作的元素(对象)的个数 
   @stream 要操作的文件 
返回值:
   成功 返回的是 成功操作到的对象的个数 
   失败 0
     到达文件结尾 返回 0
     
应用:
   主要 应用在 文件中 有固定格式的  场景 
   
   

   
  
eg:
   将3个学生的信息,写到文件中 之后,从文件中读出学生信息,打印 

#include<stdio.h>
struct student
{char name[10];int sno;float score;
};int main(int argc, const char *argv[])
{FILE* fp = fopen(argv[1],"r+");if(argc!=2){printf("Usage:%s<filename>",argv[0]);return -1;}if(fp==NULL){perror("fail open");return -1;}struct student s[3]={"tom",110,99.7,"henry",111,99.8,"jery",112,99.2};fwrite(s,sizeof(struct student ),3,fp);rewind(fp);struct student s1[3];fread(s1,sizeof(struct student ),3,fp);int i=0;for(i=0;i<3;i++){printf("%s\n",s[i].name);printf("%d\n",s[i].sno);printf("%f\n",s[i].score);}fclose(fp);return 0;
}


   
   
文件偏移量:


   rewind


   int  fseek(FILE* stream,long offset,int whence);


   功能:
       定位文件 
   参数:
      @stream  表示要操作文件 
      @offset  表示文件偏移量 
      @whence  定位的参考点 
               SEEK_SET //相对于文件开头的 
                  offset >=0 
               SEEK_CUR //相对于当前位置
                  offset>=0
                  offset<0   //不能超过这个文件开头
               SEEK_END //相对于文件末尾 
                  offset < 0  //不能超过这个文件开头
                  offset >= 0 //可以  --- 创建 空洞 文件
   返回值:
      成功 0
      失败 -1
      
                             
     fseek(fp,100,SEEK_SET);//
     fseek(fp,0,SEEK_SET);//定位到开头 
     fseek(fp,0,SEEK_END);//定位到末尾
     
     创建空洞文件: 
     1.做偏移 
     2.写操作 

#include<stdio.h>
int main(int argc, const char *argv[])
{if(argc != 3){printf("Usage:%s<filename><filename>\n",argv[0]);return -1;}FILE *fp1=fopen(argv[1],"r+");fseek(fp1,0,SEEK_END);long len = ftell(fp1);fseek(fp1,0,SEEK_SET);FILE *fp_h = fopen(argv[2],"w+");if(fseek(fp_h,len-1,SEEK_END)!=0){perror("fseek fail");return -1;}fputc('\0',fp_h);fseek(fp_h,0,SEEK_SET);char buf[100];//char buf[len];//ret=fread(buf,sizeof(buf),1,fp1);int ret;while(ret=fread(buf,sizeof(char),sizeof(buf),fp1)){fwrite(buf,sizeof(char),ret,fp_h);}fclose(fp1);fclose(fp_h);return 0;
}


     
     //空洞文件中的数据 ,都是0
     


   long ftell(FILE*stream);


   功能:
       获得当前文件的偏移量 
   void rewind(FILE*stream);
   功能:
       将文件偏移量设置到文件开头 
       
       
  获得某个文件的大小:
  1. fseek(fp,0,SEEK_END);//定位到末尾
  2. long len =ftell(fp); 
  
 
练习:
   cp   

#include<stdio.h>
int main(int argc, const char *argv[])
{if(argc!=3){printf("Usage:%s<filename><filename>",argv[0]);}FILE* fp = fopen(argv[1],"r+");FILE* fp1 = fopen(argv[2],"r+");char buf[1000];int ret;while(ret= fread(buf,sizeof(char),1000,fp)){fwrite(buf,sizeof(char),ret,fp1);}fclose(fp);fclose(fp1);	return 0;
}


    

   

   
eg:
   1.统计文件中英文字符出现的次数 

#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
int main(int argc, const char *argv[])
{if(argc!=2){printf("Usage:%s<filename>",argv[0]);return -1;}if(argv[1]==NULL){perror("fail open");return -1;}int fd = open(argv[1],O_RDONLY);unsigned char ch;int cnt[26]={0};while(read(fd,&ch,1)!=0){if(ch>='a'&&ch<='z'){cnt[ch-'a']++;}else if(ch>='A'&&ch<='Z'){cnt[ch-'A']++;}}int i;for(i=0;i<26;i++){printf("%c:%d\n",i+'a',cnt[i]);}return 0;
}


   2.
   bmp图片:
   [54头信息]
   [图像信息] //bmp图像信息 --- 原始图像 

#include<stdio.h>
//-/a.out 0.bmp 2.bmp 3.bmp
int main(int argc, const char *argv[])
{if(argc != 4){printf("usage: %s <src0.bnp> <src2.bnp> <dest.bnp>\n",argv[0]);return -1;}FILE *fp1 = fopen(argv[1],"r");FILE *fp2 = fopen(argv[2],"r");FILE *fp3 = fopen(argv[3],"w");if (fp1 == NULL || fp2 == NULL || fp3 == NULL){perror("fopen fail");return -1;}unsigned char head1[54];//unsigned char head2[54];//unsigned char body1[600*800*3];//unsigned char body2[600*800*3];//fread(head1, sizeof(unsigned char),54,fp1);fread(body1,sizeof(unsigned char),600*800*3,fp1);fread(head2,sizeof(unsigned char),54,fp2);fread(body2,sizeof(unsigned char),600*800*3,fp2);int i=0;for(i=0;i<600*800*3;i++){if (!(body1[i] == 255&&body1[i+1]==255&&body1[i+2]==255)){body2[i] =body1[i];body2[i+1] = body1[i+1];body2[i+2] =body1[i+2];}}fwrite(head2,sizeof(char),54,fp3);fwrite(body2,sizeof(char),600*800*3,fp3);fclose(fp1);fclose(fp2);fclose(fp3);return 0;
}

运行结果:
   

1.bmp

2.bmp

t.bmp


http://www.mrgr.cn/news/91393.html

相关文章:

  • 【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析④】
  • 【复现DeepSeek-R1之Open R1实战】系列4:跑通GRPO!
  • Web后端 - Maven管理工具
  • 自制简单的图片查看器(python)
  • 基于JAVA开发APISIX插件实战(1)-开发、部署、调试
  • 【私人笔记】Web前端
  • 音视频入门基础:RTP专题(9)——FFmpeg接收RTP流的原理和内部实现
  • 轮播图html
  • 级联选择器多选动态加载
  • 无缝对接[系列2]:在VSCode中继续接入本地DeepSeek的完整指南---实现代码协助编写~
  • 【机器学习】线性回归 多元线性回归
  • DeepSeek R1 与 OpenAI O1:机器学习模型的巅峰对决
  • MYSQL数据库集群高可用和数据监控平台
  • 机器学习基本篇
  • 【个人总结】1. 开发基础 工作三年的嵌入式常见知识点梳理及开发技术要点(欢迎指正、补充)
  • Sprinig源码解析
  • IMX6ULL的公板的以太网控制器(MAC)与物理层(PHY)芯片(KSZ8081RNB)连接的原理图分析(包含各引脚说明以及工作原理)
  • 计算机网络(涵盖OSI,TCP/IP,交换机,路由器,局域网)
  • Python 基础-循环
  • set的使用(c++)