zoukankan      html  css  js  c++  java
  • C语言——文件的打包与解包

    要求:将多个文件打包到同一文件,然后进行解包,解包时如果文件名重复进行标号。

    PS:这里只有打包功能,没有对大小进行压缩。

    先考虑两个问题:

    (1)解包时如何将不同文件分开?

        我们可以在写入文件内容前,提前写入一个结构体,这个结构体存有文件的大小和文件名,这样在解包时,我们总是先读出一个结构体,得到下一个文件的大小和文件名,然后按照大小读出内容即可。

    (2)如何判断文件名是否重复?

        因为是C语言,没有map映射,所以手搓了一个哈希函数进行标记(但模数不是很大,打包文件较多容易冲突)。

    一些细节的完善请自行实现。

    打包程序如下:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <time.h>
     5 #define USER_NAME_LEN 100
     6 #define EMAIL_LEN 100
     7 #define TIME_BUF_LEN 100
     8 #define FILE_NAME_LEN 300
     9 #define BUF_LEN 20
    10 #define DWORD unsigned long
    11 typedef struct FileStruct
    12 {
    13     char fileName[FILE_NAME_LEN];
    14     int fileSize;
    15 } FileStruct;
    16 char name[FILE_NAME_LEN];
    17 char buf[BUF_LEN];
    18 int getFileSize(char *fileName)
    19 {
    20     FILE* fp;
    21     if((fp=fopen(fileName,"rb"))==NULL)
    22     {
    23         printf("文件打开失败!
    ");
    24         return -1;
    25     }
    26     fseek(fp,0L,SEEK_END);
    27     int s=ftell(fp);
    28     fclose(fp);
    29     return s;
    30 }
    31 int main(void)
    32 {
    33     FILE* dfile;
    34     printf("输入目标文件名(含路径):");
    35     scanf("%s",name);
    36     if((dfile=fopen(name,"wb"))==NULL)
    37     {
    38         printf("文件打开失败!
    ");
    39         return 0;
    40     }
    41     int kase=0;
    42     FILE* sfile;
    43     while(1)
    44     {
    45         printf("输入要打包的#%d文件(含路径):",++kase);
    46         scanf("%s",name);
    47         if(strcmp(name,"exit")==0)break;
    48         if((sfile=fopen(name,"rb"))==NULL)
    49         {
    50             printf("文件打开失败!
    ");
    51             return 0;
    52         }
    53         FileStruct f;
    54         f.fileSize=getFileSize(name);
    55         if(f.fileSize==-1)return 0;
    56         strcpy(f.fileName,strrchr(name,'\')+1);
    57         if(fwrite(&f,sizeof(FileStruct),1,dfile)!=1)printf("file write error!
    ");
    58         int len=0;
    59         while((len=fread(buf,1,BUF_LEN,sfile))>=BUF_LEN)
    60         {
    61             fwrite(buf,1,BUF_LEN,dfile);
    62         }
    63         fwrite(buf,1,len,dfile);
    64     }
    65     printf("打包结束!
    ");
    66     fclose(dfile);
    67     fclose(sfile);
    68     getchar();
    69     getchar();
    70     return 0;
    71 }

    解包程序如下:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include <time.h>
     5 #define USER_NAME_LEN 100
     6 #define EMAIL_LEN 100
     7 #define TIME_BUF_LEN 100
     8 #define FILE_NAME_LEN 300
     9 #define BUF_LEN 20
    10 #define DWORD unsigned long
    11 #define ull unsigned long long
    12 typedef struct FileStruct
    13 {
    14     char fileName[FILE_NAME_LEN];
    15     int fileSize;
    16 } FileStruct;
    17 FileStruct f;
    18 char name[FILE_NAME_LEN];
    19 char buf[BUF_LEN],ans[BUF_LEN];
    20 char dic[FILE_NAME_LEN];
    21 int cnt[19260817];
    22 ull base=131,mod=19260817;
    23 ull hashs(char* s)
    24 {
    25     int len=strlen(s);
    26     ull ans=0;
    27     for(int i=0;i<len;++i)ans=(ans*base+(ull)s[i])%mod;
    28     return ans;
    29 }
    30 char* div(char* dname)
    31 {
    32     memset(ans,'',sizeof(ans));
    33     char* leave;
    34     leave=strrchr(dname,'.');
    35     int i=0;
    36     while(dname+i!=leave)
    37     {
    38         ans[i]=dname[i];
    39         ++i;
    40     }
    41     return ans;
    42 }
    43 int main(void)
    44 {
    45     printf("输入目标文件夹:");
    46     scanf("%s",dic);
    47     printf("输入要解包的文件:");
    48     scanf("%s",name);
    49     FILE* sfile;
    50     FILE* dfile;
    51     if((sfile=fopen(name,"rb"))==NULL)
    52     {
    53         printf("文件打开失败!
    ");
    54         getchar();
    55         getchar();
    56         return 0;
    57     }
    58     while(fread(&f,sizeof(FileStruct),1,sfile)==1)
    59     {
    60         char temp[BUF_LEN],part[BUF_LEN]="(0)";
    61         strcpy(temp,dic);
    62         strcat(temp,"\");
    63         strcat(temp,div(f.fileName));
    64         ull res=hashs(f.fileName);
    65         if(cnt[res]++)
    66         {
    67             part[1]+=cnt[res];
    68             strcat(temp,part);
    69         }
    70         strcat(temp,strrchr(f.fileName,'.'));
    71         if((dfile=fopen(temp,"wb"))==NULL)
    72         {
    73             printf("文件解包失败!
    ");
    74             getchar();
    75             getchar();
    76             return 0;
    77         }
    78         int left=f.fileSize;
    79         while(left)
    80         {
    81             int Size=left>BUF_LEN?BUF_LEN:left;
    82             fread(buf,Size,1,sfile);
    83             fwrite(buf,Size,1,dfile);
    84             left-=Size;
    85         }
    86     }
    87     printf("解包结束!
    ");
    88     fclose(sfile);
    89     fclose(dfile);
    90     getchar();
    91     getchar();
    92     return 0;
    93 }
    终究独木难支。
  • 相关阅读:
    约束
    TCL(事务控制语言)
    MySQL常见约束
    “三大范式”及数据库设计
    同义词(别名)
    分享35个非常漂亮的单页网站设计案例
    Eclipse智能提示 (原创)
    java架构师之路:JAVA程序员必看的15本书的电子版下载地址
    Java初级学习笔记
    Java程序的汉化
  • 原文地址:https://www.cnblogs.com/yanying7/p/14487160.html
Copyright © 2011-2022 走看看