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);
}
posted @ 2022-06-01 13:55  zongzi10010  阅读(148)  评论(0编辑  收藏  举报