文件复制二进制版

Posted 木鸟飞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件复制二进制版相关的知识,希望对你有一定的参考价值。

两种复制方式:

FILE *src = fopen("src.txt","r");

FILE *dest = fopen("dest.txt","w");

Char buf[1024]={0};

While(!feof(src)){

Size_t size = fread(buf,1,sizeof(buf),src);

Fwrite(buf,1,size,dest);

}

 

采用 stat函数

#include <sys/stat.h>

Struct stat st;

stat("src.txt",&st);

char buf[] = malloc(st.st_size);

fread(buf,st.st_size,1,src);

fwrite(buf,st.st_size,1,dest);

//记得释放内存

Free(buf);

 

 

 

这两种写法都是可以的,第二种是通过空间换时间。因为他就执行一次,所以速度很快效率很高。但是文件不能很大,所以可以做一个判断,如果文件在多大范围之内,就采用这个方式来复制,利用空间换取时间。

第一种写法是一种通吃的写法,都可以完成复制,只是速度上会比第二个慢。好处是多大都能完成复制。

但是我们一般这个缓冲区也有说法,不做的太大,也不做的太小。

太大可能造成缓冲区的浪费,太小的话移动次数会过多。

所以经过比较长久的这样一种尝试和考量决定把这个数字设定在64*1024.也就是64k。一般内存页就是64k的大小了。

 

 

下面给出一个文件复制的简单版本。当然还没有试过多大之内可以使用stat函数,并且也没有做出递归。

先来尝试文件大小的部分。

 

main.c

#include <stdio.h>
#include <sys/stat.h>
#pragma warning(disable:4996)

#define MAXSIZE4FUNC2 1038684887//一个已经检测过的大小为990Mb的zip文件。这个数是10亿个字节,所以感觉1G以内的文件都可以的。
#define _1G 1073741824//这是计算得到的1G=1073741824个字节。
#include "func1.h"
#include "func2.h"

/** 

    可以做成双击执行版本的。
    单个文件,还要迭代?
    判断当前是文件还是目录

*/
void workflow(const int,const char **);
void judgeEntrance(const char **argv, const FILE *src, FILE *dest);
int main(int argc,char **argv){
    
    workflow(argc,argv);

    //FILE *src = fopen("a.txt", "r");
    //FILE *dest = fopen("2b.txt", "w");
    //copy1(src, dest);
    //copy2("a.txt", src, dest);
    //fclose(src);
    //fclose(dest);

    return 0;
}

void workflow(const int argc, const char **argv){
    if (argc < 3){
        printf("参数过少,需要三个参数");
    }
    else if (argc>3){
        printf("参数过多,需要三个参数");
    }
    else{
    
        FILE *src = fopen(argv[1], "rb");
        FILE *dest = fopen(argv[2], "wb");
        judgeEntrance(argv,src,dest);
        fclose(src);
        fclose(dest);
    }
}
void judgeEntrance(const char **argv,const FILE *src,FILE *dest){

    struct stat st;
    stat(argv[1], &st); 
    if (st.st_size < _1G){//空间换时间的做法
        copy2(argv[1], src, dest);
    }
    else{//通配的做法
        copy1(src, dest);
    }
    printf("%d", st.st_size);
}

 

func1.h

#ifndef _FUNC1_H
#define _FUNC1_H
#include <stdio.h>

void copy1(FILE *src, FILE *dest);

#endif 

func1.c

#include <stdio.h>

void copy1(FILE *src, FILE *dest){
    char buf[1024 * 64] = { 0 };
    while (!feof(src)){
        size_t size = fread(buf, 1, sizeof(buf), src);
        fwrite(buf, 1, size, dest);
    }
}

func2.h

#ifndef _FUNC2_H
#define _FUNC2_H
#include <stdio.h>

void copy2(const char *srcstrname, const FILE *src, FILE *dest);

#endif

func2.c

#include <sys/stat.h>
#include <stdio.h>

void copy2(const char *srcstrname, const FILE *src, FILE *dest){
    struct stat st;
    stat(srcstrname, &st);
    char *buf = malloc(st.st_size);
    fread(buf, st.st_size, 1, src);
    fwrite(buf, st.st_size, 1, dest);
    free(buf);
}

 

 

 

 

以上是关于文件复制二进制版的主要内容,如果未能解决你的问题,请参考以下文章

[vscode]--HTML代码片段(基础版,reactvuejquery)

Android 片段复制

android.view.InflateException:二进制 XML 文件第 15 行:二进制 XML 文件第 19 行:膨胀类片段时出错

当我切换到包含片段的活动时应用程序崩溃(二进制 XML 文件第 10 行:二进制 XML 文件第 10 行:膨胀类片段时出错)

Mysql主从复制(重置版)

有趣的 C++ 代码片段,有啥解释吗? [复制]