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 }
终究独木难支。
原文地址:https://www.cnblogs.com/yanying7/p/14487160.html