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("文件打開失敗!\n");
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("文件打開失敗!\n");
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("文件打開失敗!\n");
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!\n");
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("打包結束!\n");
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,'\0',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("文件打開失敗!\n");
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("文件解包失敗!\n");
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("解包結束!\n");
88     fclose(sfile);
89     fclose(dfile);
90     getchar();
91     getchar();
92     return 0;
93 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM