/
DirContent.ts
145 lines (116 loc) · 4.12 KB
/
DirContent.ts
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
export { };
import * as fs from "fs";
import * as Path from "path";
interface FileOrDirectory {
path: string;
isDirectory: boolean;
children: FileOrDirectory[];
}
async function readDirByIterativeCall(path: string, filter?: string): Promise<FileOrDirectory[]> {
const entries = await fs.promises.readdir(path)
const directoryDict = new Map<number, FileOrDirectory>();
const result: FileOrDirectory[] = [];
const queue: { parentId: number, parentPath: string, entry: string }[] = [];
let directoryId = 0;
for (const entry of entries) {
queue.push({ parentId: 0, parentPath: path, entry });
}
while (queue.length > 0) {
const element = queue.shift()!;
const absolutePath = Path.join(element.parentPath, element.entry);
if (filter) {
const regex = new RegExp(filter);
if (!regex.test(absolutePath)) {
continue;
}
}
const addedEntry: FileOrDirectory = {
path: element.entry,
isDirectory: fs.lstatSync(absolutePath).isDirectory(),
children: [],
};
if (addedEntry.isDirectory) {
directoryId++;
const childEntries = await fs.promises.readdir(absolutePath);
for (const entry of childEntries) {
queue.push({ parentId: directoryId, parentPath: absolutePath, entry });
}
directoryDict.set(directoryId, addedEntry);
}
if (element.parentId === 0) {
result.push(addedEntry);
} else {
const parentEntry = directoryDict.get(element.parentId);
if (!parentEntry) {
throw new Error(`parent ID doesn't exist in the directoryDict. [${element.parentId}]`);
}
parentEntry.children.push(addedEntry);
}
}
return result;
}
async function readDirByRecursiveCall(path: string, filter?: string): Promise<FileOrDirectory[]> {
const entries = await fs.promises.readdir(path)
const result: FileOrDirectory[] = [];
for (const entry of entries) {
const absolutePath = Path.join(path, entry);
if (filter) {
const regex = new RegExp(filter);
if (!regex.test(absolutePath)) {
continue;
}
}
const addedEntry: FileOrDirectory = {
path: entry,
isDirectory: fs.lstatSync(absolutePath).isDirectory(),
children: [],
};
if (addedEntry.isDirectory) {
addedEntry.children = await readDirByRecursiveCall(absolutePath);
}
result.push(addedEntry);
}
return result;
}
function showItem(item: FileOrDirectory, depth: number): string {
if (item.isDirectory) {
const result = [];
result.push(" ".repeat(depth * 2) + item.path + "\n");
if (item.children.length === 0) {
return " ".repeat(depth * 2) + "empty\n";
}
for (const child of item.children) {
result.push(showItem(child, depth + 1));
}
return result.join("");
} else {
return " ".repeat(depth * 2) + item.path + "\n";
}
}
async function run() {
{
console.log("----- readDirByIterativeCall -----")
const items = await readDirByIterativeCall("D:/temp/test");
const msg = items.map((v) => showItem(v, 0)).join("");
console.log(msg);
}
{
console.log("----- readDirByIterativeCall with filter-----")
const items = await readDirByIterativeCall("D:/temp/test", "secondDir");
const msg = items.map((v) => showItem(v, 0)).join("");
console.log(msg);
}
{
console.log("----- readDirByRecursiveCall -----")
const items = await readDirByRecursiveCall("D:/temp/test");
const msg = items.map((v) => showItem(v, 0)).join("");
console.log(msg);
}
{
console.log("----- readDirByRecursiveCall with filter-----")
const items = await readDirByRecursiveCall("D:/temp/test", "secondDir");
const msg = items.map((v) => showItem(v, 0)).join("");
console.log(msg);
}
}
run().then();