forked from cuncinc/FileManageSystem
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BiTreeOpe.c
373 lines (329 loc) · 8.65 KB
/
BiTreeOpe.c
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
#include "NodeInfo.h"
#include "State.h"
#include "NodeOpe.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//获取文件状态所需的头文件
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#define MAX_SPACING 15 //最大的输出间距,超过这个间距,剩余的字符就会被截断
/*
* Author: 谢文?? Modify:宋??
* 作用:返回文件目录下的所有文件名路径
* 用法:参数path是文件的绝对路径,path不存在返回NULL
*/
char **get_inner_pathes(FileInfo *info)
{
int strLength;
char *path = info->path;
char **paths_arr = (char ** )malloc(sizeof(char* ) * info->innerFileNum); //动态分配内存空??
DIR *dir = opendir(path);
struct dirent *entry;
int num = 0;
int lenth = strlen(path); //获取文件路径的长??
if(paths_arr == NULL || dir == NULL)//若path为空路径不存??,或内存分配失败,返回NULL
{
return NULL;
}
//把小圆点去掉
readdir(dir);
readdir(dir);
char **p;
for (p=paths_arr ; num < info->innerFileNum; ++p, ++num)
{
entry = readdir(dir);
// printf("%d: " , num);
// char *name = (char *)malloc(sizeof(char) * (strlen(entry->d_name)+1));
// strcpy(name, entry->d_name);
// printf("%s:.1\n", __func__);
strLength = strlen(path) + entry->d_namlen + 2;
// printf("strlen = %d\n", strLength);
char *tmp = (char *)malloc(strLength * sizeof(char));
if (tmp==NULL)
{
printf("NULL Pointer\n");
}
// printf("%s:.2\n", __func__);
*p = tmp;
// 另两个空间,一个是\\,一个是\0
if(*p == NULL) //空间分配失败,返回NULL
{
return NULL;
}
strcpy(*p, path);
*((*p)+lenth) = '\\';
// p[lenth] = '\\'; //分隔??
// strcpy(paths_arr[num]+lenth+1, entry->d_name); //生成绝对路径
strcpy((*p)+lenth+1, entry->d_name);
}
closedir(dir);
// printf("%s:end", __func__);
return paths_arr;
}
/*
* Author:宋??
* 功能:只建立path文件夹下的同一层的兄弟二叉??(退化为链表)
*/
FilesBiTree create_blising_tree(char *path)
{
FilesBiTree root = (FilesBiTree) malloc (sizeof(FileNode));
FileNode *node = root;
if( node == NULL || NULL == path || 0==strlen(path)
|| (!file_exsists(path) && !folder_exsists(path))) //若分配空间失??
{
return NULL;
}
node->rch = NULL;
node->info = create_info_node(path); //获取文件信息
int fileNum = node->info->innerFileNum;
char **p = get_inner_pathes(node->info); //获取文件夹内的文件路??
int i;
node->lch = (FilesBiTree) malloc (sizeof(FileNode));
node = node->lch;
node->info = create_info_node(p[0]);
node->lch = NULL;
for(i = 1; i < fileNum; ++i)
{
node->rch = (FilesBiTree) malloc (sizeof(FileNode)); //右子结点为目录下的后面文??
node = node->rch;
node->lch = NULL;
node->info = create_info_node(p[i]);
}
node->rch = NULL; //到了最后一个右孩子
return root;
}
/*
* Author: 谢文?? Modify:宋淳
* 作用:返回文件目录二叉树的根节点
* 用法:参数path是文件的绝对路径,path不存在返回NULL
*/
FilesBiTree create_files_bitree(char *path)
{
FilesBiTree root = (FilesBiTree) malloc (sizeof(FileNode));
if(root == NULL || (!file_exsists(path) && !folder_exsists(path)))
{
return NULL;
}
root->info = create_info_node(path); //获取文件信息
if(root->info == NULL) //若文件不存在,返回NULL
{
free(root);
return NULL;
}
if(file == root->info->type) //如果是文??
{
root->lch = NULL;
}
else //如果是文件夹
{
if (0 == root->info->innerFileNum) //若为空文件夹
{
root->lch = NULL;
return root;
}
char **p = get_inner_pathes(root->info); //获取文件夹内的文件路??
root->lch = create_files_bitree(p[0]); //左子结点为目录下的第一?? 文件
FilesBiTree pointer = root->lch;
int i;
for(i = 1; i < root->info->innerFileNum; i++)
{
pointer->rch = create_files_bitree(p[i]); //右子结点为目录下的后面文??
pointer = pointer->rch;
}
pointer->rch = NULL; //到了最后一个右孩子
}
root->rch = NULL;
return root;
}
/*
* Author:宋淳
* 实现功能:只输出此目录下的文??(??)的名字,按列对齐
*/
int list_files_name_only(FilesBiTree tree)
{
FileNode *node = tree;
if (node->info->type != folder) //若不是文件夹,直接退??
{
return Error;
}
if (NULL == node->lch) //若是空文件夹,提示并退??
{
printf("空文件夹\n");
return OK;
}
FilesBiTree p = tree->lch;
int maxLength = 0;
int tempLength = 0;
int spacing = 0;
int i;
for (i=0; i<(node->info->innerFileNum); ++i, p=p->rch)
{
if (maxLength < (tempLength=strlen(p->info->name)))
{
maxLength = tempLength;
}
}
//获取间隔,若字符串的最大宽度大于预设的最大宽度,则间隔为预设的最大宽??
spacing = maxLength < MAX_SPACING ? maxLength : MAX_SPACING;
p = tree->lch; //从头开始输??
// printf("%d %d\n", maxLength, spacing);
for (i=1; i<node->info->innerFileNum; ++i, p=p->rch)
{
print_name(p->info->name, spacing);
if (0 == i%4)
{
printf("\n");
}
}
printf("\n");
return OK;
}
/*
* Author:宋??
* 作用:只输出此目录下的文??(??)的名字,按列对齐
*/
int list_files_name_only_in_path(char *path)
{
FilesBiTree blisingTree = create_blising_tree(path);
list_files_name_only(blisingTree);
free_tree(blisingTree);
return OK;
}
FileNode *locate_node(char *path, FilesBiTree root)
{
if(root == NULL || path == NULL) //如果路径不存在或者根节点不存在,返回NULL
{
return NULL;
}
if(strcmp(path, root->info->path) == 0 && root->info->type == folder)
{
return root;
}
FileNode *node1 = locate_node(path,root->rch);
if(node1 != NULL)
return node1;
FileNode *node2 = locate_node(path, root->lch);
if(node2 != NULL)
return node2;
return NULL;
}
int copy_folder(char *destPath, FileNode *sourceNode, FilesBiTree root)
{
if( destPath == NULL || sourceNode == NULL || root == NULL || file_exsists(destPath)) //如果待复制路径为文件或其他异常
{
return Error;
}
FilesBiTree cloneSourceNode = (FilesBiTree)malloc(sizeof(FileNode));
if(cloneSourceNode == NULL) //若分配内存空间失败
{
return Error;
}
// 兼容性不好,不同的终端有不同的命令
// // 创建命令
// char command[300];
// char *p = command;
// strcpy(p, "copy ");
// p += strlen("copy ");
// strcpy(p, sourceNode->info->path);
// p += strlen(sourceNode->info->path);
// strcpy(p, destPath);
// p +=strlen(destPath);
// *p = '\0';
// printf("%s\n", command);
// system(command); //执行系统的cp函数
cloneSourceNode = create_files_bitree(sourceNode->info->path);
if(cloneSourceNode == NULL) //若分配内存空间失败
{
return Error;
}
FileNode *destNode = locate_node(destPath, root); //定位到待复制的结点
//用头插法
cloneSourceNode->rch = destNode->lch;
destNode->lch = cloneSourceNode;
return OK;
}
/*
* 实现功能:在一行中输出一个文件(夹)的文件(夹)命,大小,时间
* 实验要求:
* 1. 判断是不是文件夹,为空文件夹直接返回
* 2. 列与列间要对齐,参考在PowerShell中ls命令的样式
*/
int list_files(FilesBiTree tree)
{
if(tree->info->type == file || tree->info->innerFileNum == 0) //如果为文件或者为控股文件夹
{
return Error;
}
if(tree == NULL)
{
return Error;
}
int i;
FilesBiTree node = tree->lch;
printf("\tDIR: %s\n", tree->info->path);
printf("\tTotal: %d\n", tree->info->innerFileNum);
if (0 == tree->info->innerFileNum)
{
printf("\tEmpty Direction.\n");
}
print_name("Name", 22);
printf("\t");
print_name("MofifyTime", 24);
printf("\t");
print_name("Size", 10);
printf("\n");
print_name("----", 22);
printf("\t");
print_name("-----------", 24);
printf("\t");
print_name("----", 10);
printf("\n");
for(i = 0; i < tree->info->innerFileNum; i++)
{
print_name(node->info->name, 22);
printf("\t");
print_name(node->info->modifyTime, 24);
printf("\t");
if(node->info->type == file)
{
char *string = get_size_string(node->info->size);
print_name(string, 10);
// free(string); //会出bug
}
else
{
printf("<DIR>");
}
printf("\n");
node = node->rch;
}
printf("\n");
return OK;
}
int list_files_in_path(char *path)
{
FilesBiTree blisingTree = create_blising_tree(path);
list_files(blisingTree);
free_tree(blisingTree);
return OK;
}
// /*
// * 返回类型:OK表示成功执行,ERROR表示执行失败
// * 实现功能:打印此目录下的文件(夹),参考在powerShell中使用tree命令的效果
// * 实现要求:
// * 1. 要先判断接收到的是文件还是文件夹
// * 2. 若文件夹为空,则直接返回
// * 3. 递归调用,输出此文件夹下的所有文件(夹)
// */
// int tree_files(FilesBiTree tree)
// {
// if (NULL == tree)
// {
// return;
// }
// printf("%s", tree->info->name);
// printf()
// }