0%

计算机网络实验四_文件打包实验

文件打包实验

实验目的

掌握文件打包的方法

参考资料

C语言字符串函数:http://msdn.microsoft.com/zh-cn/library/f0151s4x(v=vs.110).aspx
C语言程序设计:http://www.runoob.com/cprogramming/
C语言函数分类:http://msdn.microsoft.com/zh-cn/library/2aza74he(v=vs.110).aspx

实验环境

WSL+ gcc

实验内容

把输入的结构数据保存到文件中

实验要求

循环输入员工(Person)的信息,每输入一个员工的信息,立即写入文件(Persons.stru),直到输入的姓名为exit时跳出循环。
Person的信息表示:

1
2
3
4
5
6
7
struct Person {
char username[USER_NAME_LEN]; // 员工名
int level; // 工资级别
char email[EMAIL_LEN]; // email地址
DWORD sendtime; // 发送时间
time_t regtime; // 注册时间
};

完成后截屏运行结果

image.png

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include <string.h>
#define USER_NAME_LEN 100
#define EMAIL_LEN 100
#define BUF_LEN 100
#define TIME_BUF_LEN 100
#define PERSON_BUF_LEN 300
struct Person{
char userName[USER_NAME_LEN];
int level;
char email[EMAIL_LEN];
long long sendtime;
time_t regtime;
}person;

char text_buf[BUF_LEN];
int level_buf;
char pts[TIME_BUF_LEN];
time_t now;
char person_buf[PERSON_BUF_LEN];

int main(void){
FILE* file=fopen("Person.txt","wb");
if(file==NULL){
printf("File open error!\n");
abort();
}
while(1){
printf("name:");
scanf("%s",text_buf);
if(strcmp("exit",text_buf)==0){
printf("Exit input!\n");
break;
}
strncpy(person.userName,text_buf,USER_NAME_LEN);
printf("level:");
scanf("%d",&level_buf);
person.level=level_buf;
printf("email:");
scanf("%s",text_buf);
strncpy(person.email,text_buf,EMAIL_LEN);
time(&now);
person.sendtime=(long long)now;
person.regtime=now;
memcpy(person_buf,&person,sizeof(struct Person));
if(fwrite(person_buf,PERSON_BUF_LEN,1,file)!=1){
printf("Write file error!\n");
abort();
}
}
fclose(file);
}

从文件读出结构数据并显示出来

完成后截屏运行结果

image.png

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include <string.h>
#define USER_NAME_LEN 100
#define EMAIL_LEN 100
#define BUF_LEN 100
#define PERSON_BUF_LEN 300
struct Person{
char userName[USER_NAME_LEN];
int level;
char email[EMAIL_LEN];
long long sendtime;
time_t regtime;
}person;


char person_buf[PERSON_BUF_LEN];
int main(void){

FILE* file2=fopen("Person.txt","rb");
while(fread(person_buf,PERSON_BUF_LEN,1,file2)!=0){
// printf("%s",person_buf);
memcpy(&person,person_buf,PERSON_BUF_LEN);
printf("姓名:%s 级别:%d 电子邮件:%s 发送时间%s 注册时间%s\n",person.userName,person.level,person.email,ctime(&person.sendtime),ctime(&person.regtime));
}
fclose(file2);
}

打包文件 (FilePack.c)

实验要求

(1) 先输入打包文件名(含路径);
(2) 循环输入要打包的文件名(含路径),每输入一个,就把该文件的文件名(最多300字节)、文件大小(long)和文件内容写入文件FileSet.pak中,当输入文件名为exit时跳出循环。
当前文件夹下有FilePack和FilePack.c等多个文件
image.png

运行程序

image.png
生成的dest文件:
image.png

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include <string.h>
#define BUF_LEN 100
#define PERSON_BUF_LEN 300
#define FILE_NAME_LEN 300

struct FileStruct {
char fileName[300];
long long fileSize;
};
long long getFileSize(char * fileName){
FILE* fp=fopen(fileName,"r");
fseek(fp, 0, SEEK_END);
size_t size = ftell(fp);
fclose(fp);
return size;
}
char * getFileName(char *pathName){
while(*pathName!='\0')pathName++;
while(*pathName!='/')pathName--;
return pathName+1;
}

char text_buf[BUF_LEN];
time_t now;
char person_buf[PERSON_BUF_LEN];
char file_NAME[FILE_NAME_LEN];
int main(void){
printf("输入要目标文件名(含路径):");
scanf("%s",text_buf);
FILE* file3=fopen(text_buf,"wb");
int now=0;
while(1){
now++;
printf("输入要打包的#%d文件(含路径):",now);
scanf("%s",text_buf);
if(strcmp(text_buf,"exit")==0){
printf("打包结束!\n");
break;
}
struct FileStruct f;
f.fileSize=getFileSize(text_buf);
strcpy(f.fileName,getFileName(text_buf));
int a=fwrite(&f,sizeof(struct FileStruct),1,file3);
FILE* tem_file=fopen(text_buf,"r");
char* content=(char*)malloc(f.fileSize);
fread(content,f.fileSize,1,tem_file);
fclose(tem_file);
fwrite(content,f.fileSize,1,file3);
}
fclose(file3);
}

解包文件 (FileUnpack.c)

实验要求

(1)输入解包路径
(2)输入打包文件名,然后解包其中每一个文件,有重名文件时文件名加上序号(从2开始)。

先把几个文件打包进dest文件中,然后解包.

运行结果:
image.png
new文件夹的内容变为:
image.png

五个文件均可打开,显示内容正常,字节数与源文件相同:
image.png

源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include <string.h>
#define BUF_LEN 100
#define PERSON_BUF_LEN 300
#define FILE_NAME_LEN 300
//#define FILE_CONTENT_LEN 100000

struct FileStruct {
char fileName[300];
long long fileSize;
};
long long getFileSize(char * fileName){
FILE* fp=fopen(fileName,"r");
fseek(fp, 0, SEEK_END);
size_t size = ftell(fp);
fclose(fp);
return size;
}
char * getFileName(char *pathName){
while(*pathName!='\0')pathName++;
while(*pathName!='/')pathName--;
return pathName+1;
}

void Unpack(struct FileStruct* fileStruct,char* file_content,char* folder_name){
char* Full_name[FILE_NAME_LEN];
sprintf(Full_name,"%s/%s",folder_name,fileStruct->fileName);
// printf("%s\n",Full_name);
FILE* file=fopen(Full_name,"wb");
fwrite(file_content,sizeof(char),fileStruct->fileSize,file);
return;
}

void add_suffix(char* new_filename,int occur_time,char* old_filename){
char* tem=old_filename;
while(*tem!='\0')tem++;
while(*tem!='.'&&tem!=old_filename)tem--;
if(tem!=old_filename){
*tem='\0';
sprintf(new_filename,"%s(%d).%s",old_filename,occur_time,tem+1);
*tem='.';
return;
}
else{
sprintf(new_filename,"%s(%d)",old_filename,occur_time);
return;
}
}


char text_buf[BUF_LEN];
char person_buf[PERSON_BUF_LEN];
char file_NAME[FILE_NAME_LEN];
char dest_folder[FILE_NAME_LEN];
char* file_content;
char file_names[BUF_LEN][FILE_NAME_LEN];
int occur_times[BUF_LEN];
int file_name_count=0;

int main(void){
printf("输入要目标文件夹:");
scanf("%s",dest_folder);
printf("输入要解压的文件:");
scanf("%s",file_NAME);
FILE* f=fopen(file_NAME,"rb");
struct FileStruct fileStruct;
while(fread(&fileStruct,sizeof(struct FileStruct),1,f)!=0){
file_content=(char*)malloc(fileStruct.fileSize);
printf("%d",fileStruct.fileSize);
fread(file_content,sizeof(char),fileStruct.fileSize,f);
int ok=0;
for(int i=0;i<file_name_count;i++){
if(strcmp(file_names[i],fileStruct.fileName)==0){
occur_times[i]++;
int occur_time=occur_times[i];
add_suffix(file_NAME,occur_time,fileStruct.fileName);
strcpy(fileStruct.fileName,file_NAME);
ok=1;
break;
}
}
if(ok==0){
strcpy(file_names[file_name_count],fileStruct.fileName);
occur_times[file_name_count++]++;
}
Unpack(&fileStruct,file_content,dest_folder);
}

}

与同学互测并截屏运行结果

对同学发过来的这个文件进行解包:
image.png
解包正常:
image.png
image.png
把我的dest文件发给同学后,解包结果如下:
image.png
结果正常,证明不同操作系统的打包文件也可以被互相解包。

实验体会

这次实验算很简单了,并没有用到计算机网络中的什么知识,唯一比较难的是对文件的读写操作,通过查阅资料也能解决。借着这次实验复习了一下c语言中的各种基础知识,也算是一个不错的收获吧。