• fseek写文件


    fseek写文件

    FAQ

    从串口或者网络接收文件,文件分包带序号,一开始用ab+的形式,发现如果中间丢失了一包数据之后,fseek不会跳过这个区域,直接在尾巴追加,遂仔细翻看APUE,以及编写测试代码

    API相关

    
    FILE *fopen(const char *restrict pathname, const char *restrict mode);
    
    // SEEK_SET 文件头的偏移
    int fseek(FILE *stream, long offset, int whence);
    long ftell(FILE *stream);
    
    void rewind(FILE *stream);
    
    int fgetpos(FILE *restrict stream, fpos_t *restrict pos);
    int fsetpos(FILE *stream, const fpos_t *pos);
    

    文件读写模式

    r	可读
    w	可写
    +	允许读写,具有下列限制:
    		如果中间没有fflush、fseek、fsetpos或rewind,则在输出的后面不能直接跟随输入。
    		如果中间没有fseek、fsetpos或rewind,或者一个输出操作没有到达文件尾端,则在输入操作之后不能直接跟随输出
    
    b	二进制,在linux没区别,win上有用
    a	追加形式,只允许在尾巴写
    

    image-20220601133927632

    image-20220601133944247

    模式配合seek

    • 使用带a的选项,只能追加在尾巴,即使fseek超出文件尾,也只是在EOF的位置追加
    • 使用rb+/wb的形式,fseek可以留空写,但是w会提前清空文件
    • 使用rb+,可以实现fseek到指定位置来读写
    • fseek只能用替换,不能实现插入功能
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    // 测试ab+ 的seek 的功能
    void wa(unsigned char * mode,int addr,char val )
    {
        FILE* fp = fopen("info",mode);
        if(fp== 0)
        {
            printf("wa ERROR  mode=%s\r\n",mode);
            return ;
        }
        
        int f_ret=fseek(fp,addr,SEEK_SET);
        if(f_ret!=0)
        {
            printf("fseek ERROR  mode=%s\r\n",mode);
            return ;
        }
    
        f_ret=fwrite(&val,sizeof(val),1,fp);
        if(f_ret!=1)
        {
            printf("wa write File Error mode=%s \r\n",mode);
            return;
        }
        fclose(fp);
        printf("write File  mode=%s,@%d,=%c\r\n",mode,addr,val);
        printf("hexdump -C info\r\n");
        system("hexdump -C info");
        
    }
    
    
    void Init()
    {
        FILE* fp = fopen("info","w+");
        if(fp!= 0)
        {
            char initBuf[]="0123456789";
            int f_ret=fwrite(initBuf,sizeof(initBuf),1,fp);
            if(f_ret!=1)
            {
                printf("Init File Error\r\n");
                return ;
            }
            fclose(fp);
        }
        printf("Init File Success\r\n");
        printf("hexdump -C info\r\n");
        system("hexdump -C info");
    }
    
    int main ()
    {
        printf("\r\n\r\n\r\n\r\n\r\n#############Test fopen###########\r\n\r\n\r\n");
        Init();
        printf("// ab+ 即使fssek 到中间位置,也是在尾巴写入\r\n");
        wa("ab+",2,'A');
        Init();
         printf("// ab+ 即使fssek 抄出文件尾巴,也是在尾巴写入,不会留空\r\n");
        wa("ab+",100,'A');
        Init();
         printf("// rb+ fssek 到中间,是走文字替换\r\n");
        wa("rb+",2,'A');
        Init();
         printf("// rb+ fssek 超出文件,会留空追加\r\n");
        wa("rb+",100,'A');
        Init();
         printf("// wb+ fssek 超出文件,会留空追加, 提前都会清空文件\r\n");
        wa("wb+",100,'A');
         printf("// wb fssek 超出文件,会留空追加, 提前都会清空文件\r\n");
        Init();
        // wb 是不能读的
        //wa("wb",100,'A');
        return(0);
    }
    
  • 相关阅读:
    开发模式的问题
    day70-springmvc day75-springmvc 2springmvc架构
    09-SSH综合案例:前台用户模块:注册功能实现
    Win10不可不知的常用技巧,建议收藏!
    Win10不可不知的常用技巧,建议收藏!
    Win10不可不知的常用技巧,建议收藏!
    Jquery操作CSS常用方法
    Jquery操作CSS常用方法
    Jquery操作CSS常用方法
    前端必备知识点—SVG
  • 原文地址:https://www.cnblogs.com/zongzi10010/p/16334030.html
Copyright © 2020-2023  润新知