C语言文件切割、合并

分割与合并的思想

1. 分割:和安卓多线程下载类似 ,首先将文件长度按N段分,然后将每段文件读取并写入到相应的临时文件,以达到分割的目的
2. 合并:将每段临时文件依次读取,然后写入到要合并成的新文件

注意细节
 1. 文件打开后记得要关闭
 2. 对文件打开的状态进行判断,处理异常
 3. fgets函数会获取行尾的\n,必要时进行相关处理,fputs输入字符串时不会自动添加\n
 4. 对最后一块的长度进行特殊处理,因为它不一定等于每一块的长度
 5. 对操作的分割合并的文件使用二进制的模式进行打开
 6. 注意feof函数的使用,在文件指针指向EOF时,下一次读取feof才会返回1
 

源代码

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
int main(){
    char file_path[] = "D:\\a.txt";
    FILE *file = fopen(file_path,"w");
    char content[] = "I Have a Dream";
    fputs(content,file);
    fclose(file);
    getchar();
    return 0;
}
*/
/*
int main(){
    struct Student{
        char name[10];
        int num;
        int age;
        char addr[30];
    } stud[10];
    char file_path[] = "D:\\stud.dat";
    FILE * output = fopen(file_path,"w");
    if(output == NULL){
        printf("无法打开文件");
        exit(0);
    }
    for(int i=0;i<10;i++)
        scanf("%s %d %d %s",stud[i].name,&stud[i].num,&stud[i].age,stud[i].addr);
        fwrite(&stud[i],sizeof(struct Student),1,output);
    }
    flose(output);
    getchar();
    return 0;
}
*/
//获取文件大小
int getFileSize(char old_file_path[])
{
    FILE *file = fopen(old_file_path, "r");
    fseek(file, 0, SEEK_END);
    long fileSize = ftell(file);
    return fileSize;
}
/*
int main(){
     //分为两步
     //第一步:获取分割文件名称
     //源文件
     char source_file_path[] = "D:\\timg.gif";
     int file_number = 6;
     //开辟一块内存区域:用于存储文件的名称(二维指针)
     //存放字符串(二维字符指针)
     //首先:char *p = source_file_path;--首地址(字符串)
     //char source_file_path[] = "/Users/yangshaohong/Desktop/icon_image_1.gif";
     //char source_file_path[] = "/Users/yangshaohong/Desktop/icon_image_2.gif";
     //char source_file_path[] = "/Users/yangshaohong/Desktop/icon_image_3.gif";
     char **file_name_array = (char**)malloc(sizeof(char*)*file_number);
     for(int i = 0 ; i < file_number ; i++){
         //开辟内存空间,用于存放文件路径
         file_name_array[i] = (char*)malloc(sizeof(char)*300);
         //赋值(字符串的格式化:sprintf)
         //结果:/Users/yangshaohong/Desktop/icon_image_0.gif
         //结果:/Users/yangshaohong/Desktop/icon_image_1.gif
         sprintf(file_name_array[i],"D:\\timg_%d.gif",i);
         printf("文件名称:%s\n",file_name_array[i]);
     }

     //第二步:向指定的分割文件写入内容
     //分析问题:每一个文件大小是多少?
     //假设:源文件大小51  分割成6个文件   每一个文件的大小?
     //两种情况:第一种情况能够平分(54%6=0)
     //第二种情况不能够平分(50%6!=0)
     //例如:源文件大小51  分割成6个文件  前5个10  最后1个1
     //例如:源文件大小51  分割成7个文件  前6in?51/(7-1)=8  最后1个51%(7-1)=3
     //例如:源文件大小51  分割成8个文件  前7个51/(8-1)=7  最后1个51%(8-1)=2
     //例如:源文件大小51  分割成11个文件  前10个51/(11-1)=5  最后1个51%(11-1)=1
     //以此类推: 源文件大小num  分割成n个  前n-1个大小=num/(n-1)  最后1个大小=num%(n-1)
     long file_size_sum = getFileSize(source_file_path);
     //打开源文件
     FILE *source_p = fopen(source_file_path,"rb");
     if(file_size_sum%file_number == 0){
         //平均分
         //计算每一个分割文件大小
         long file_size = file_size_sum / file_number;
         //遍历:写入内容
         //外层循环控制分割文件,内存循环控制文件的写入
         for(int i = 0;i<file_number;i++){
             //打开分割文件
             FILE *file_cut = fopen(file_name_array[i],"wb");
             for(int j = 0 ;j<file_size;j++){
                 //参数一:获取源文件内容
                 //参数二:写入分割-目标文件
                 fputc(fgetc(source_p),file_cut);
             }
             //关闭当前分割文件流
             fclose(file_cut);
         }
         //关闭源文件流
         fclose(source_p);
     }else{
        //不均等
        //计算每一个分割文件大小
         long file_size = file_size_sum / (file_number-1);

         //处理前面的分割文件
         //遍历:写入内容
         //外层循环控制分割文件,内存循环控制文件的写入
         for(int i = 0;i<file_number-1;i++){
             //打开分割文件
             FILE *file_cut = fopen(file_name_array[i],"wb");
             for(int j = 0 ;j<file_size;j++){
                 //参数一:获取源文件内容
                 //参数二:写入分割-目标文件
                 fputc(fgetc(source_p),file_cut);
             }
             //关闭当前分割文件流
             fclose(file_cut);
         }

         //写入最后一个文件(单独处理)
         //打开分割文件
         //打开最后一个文件
         FILE *file_last_cut = fopen(file_name_array[file_number - 1],"wb");
         long last_file_size = file_size_sum % (file_number-1);
         //你不这么做,后面会填写'\0'
         for(int j = 0 ;j<last_file_size;j++){
            //参数一:获取源文件内容
            //参数二:写入分割-目标文件
            fputc(fgetc(source_p),file_last_cut);
         }
         //关闭当前分割文件流
         fclose(file_last_cut);

         //关闭源文件流
         fclose(source_p);
   }

    getchar();
    return 0;
}
*/

//合并文件
int main()
{
    //分为两步
    //第一步:获取分割文件名称
    //源文件
    char source_file_path[] = "D:\\timg.gif";
    //合并之后的文件路径
    char merge_file_path[] = "D:\\timg_marge.gif";

    int file_number = 6;

    //开辟一块内存区域:用于存储文件的名称(二维指针)
    //存放字符串(二维字符指针)
    char **file_name_array = (char **)malloc(sizeof(char *) * file_number);
    for (int i = 0; i < file_number; i++)
    {
        //开辟内存空间,用于存放文件路径
        file_name_array[i] = (char *)malloc(sizeof(char) * 300);
        //赋值(字符串的格式化:sprintf)
        sprintf(file_name_array[i], "D:\\timg_%d.gif", i);
        printf("文件名称:%s\n", file_name_array[i]);
    }

    //合并文件
    
    //打开源文件
    FILE *merge_p = fopen(merge_file_path, "wb");
    for (int i = 0; i < file_number; i++)
    {
        //计算每一个分割文件的大小
        long file_size_sum = getFileSize(file_name_array[i]);
        //打开分割文件,重分割的文件中读取内容
        FILE *file_cut = fopen(file_name_array[i], "rb");
        for (int j = 0; j < file_size_sum; j++)
        {
            //参数一:分割文件(源文件)
            //参数二:写入合并的文件-目标文件
            //加密也是一样的,将fgetc(file_cut)按照我们之前的做法进行
            fputc(fgetc(file_cut), merge_p);
        }
        //关闭当前分割文件流
        fclose(file_cut);
    }
    //关闭源文件流
    fclose(merge_p);

    getchar();
    return 0;
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值