1
+ using System . Diagnostics ;
2
+ using System . Runtime . Serialization . Formatters . Binary ;
3
+ using TreeIterator ;
4
+ using TreeIterator . TestApp ;
5
+ // ReSharper disable RedundantAssignment
6
+ #pragma warning disable SYSLIB0011
7
+
8
+ bool iterate = true ;
9
+ TreeEnumerationMode enumerationMode = TreeEnumerationMode . DepthFirst ;
10
+
11
+ EnterSelection :
12
+ Console . Clear ( ) ;
13
+ Write ( "Please choose what you want to do:" ) ;
14
+ Write ( "1 - Mirror directory in tree, iterate it (timing), serialize " +
15
+ "tree binary (legacy + custom), as XML and dump it as text." ) ;
16
+ Write ( "2 - Deserialize from legacy binary file" ) ;
17
+ Write ( "3 - Deserialize from custom binary file" ) ;
18
+ Write ( "4 - Deserialize from XML" ) ;
19
+ Write ( $ "5 - Change deserialization iteration on/off [Current: { iterate } ]") ;
20
+ Write ( $ "6 - Change enumeration mode Depth/Breadth [Current: { enumerationMode } - Color " +
21
+ "Code: " + ( enumerationMode == TreeEnumerationMode . DepthFirst ? "Cyan" : "Green" ) + "]" ) ;
22
+ Write ( "7 - Exit" ) ;
23
+
24
+ if ( ! int . TryParse ( Console . ReadLine ( ) , out var selection ) )
25
+ goto EnterSelection ;
26
+
27
+ Stopwatch stopwatch = new ( ) ;
28
+
29
+ if ( selection == 1 )
30
+ {
31
+ EnterPath :
32
+ Write ( "Enter any directory which should be built as tree (or enter for the test directory [recommended]:" ) ;
33
+ string ? rootDir = Console . ReadLine ( ) ;
34
+ if ( string . IsNullOrEmpty ( rootDir ) )
35
+ {
36
+ rootDir = Path . Combine ( Environment . CurrentDirectory , "Test Folder" ) ;
37
+ }
38
+
39
+ DirectoryInfo root ;
40
+ try
41
+ {
42
+ root = new ( rootDir ) ;
43
+ if ( ! root . Exists ) throw new ( ) ;
44
+ }
45
+ catch
46
+ {
47
+ Write ( "Yeah sure thing, but that ain't no valid directory. Once again..." , ConsoleColor . Red ) ;
48
+ goto EnterPath ;
49
+ }
50
+
51
+ string output = Path . Combine ( Environment . CurrentDirectory , "fsTree.txt" ) ;
52
+ Write ( $ "A tree of the file system structure will be built now. " +
53
+ $ "The output will be placed inside '{ output } '.", ConsoleColor . Cyan ) ;
54
+ Write ( "Depending on your directory this might take a while. Don't close the application! Stuff is happening right now." ,
55
+ ConsoleColor . Yellow ) ;
56
+
57
+ // Build tree
58
+ FileSystemTreeBranch rootBranch = new ( root . Name , true ) ;
59
+ FileSystemTree tree = new ( rootBranch ) ;
60
+
61
+ BuildTree ( root , rootBranch ) ;
62
+
63
+ Write ( "The tree is built up. Press key to start iteration. WARNING: No real performance test!" , ConsoleColor . Yellow ) ;
64
+ Console . ReadLine ( ) ;
65
+
66
+ Console . ForegroundColor = ConsoleColor . Magenta ;
67
+ tree . EnumerationMode = TreeEnumerationMode . BreadthFirst ;
68
+
69
+ // Cold run-through
70
+
71
+ stopwatch . Start ( ) ;
72
+ foreach ( var _ in tree )
73
+ {
74
+ }
75
+
76
+ stopwatch . Stop ( ) ;
77
+ Write ( $ "Breadth-first cold run-through: { stopwatch . Elapsed . TotalMilliseconds } ms ({ stopwatch . Elapsed . TotalSeconds } s).",
78
+ ConsoleColor . Red ) ;
79
+
80
+ // Warm run-through
81
+ stopwatch . Restart ( ) ;
82
+ foreach ( var _ in tree )
83
+ {
84
+ }
85
+
86
+ stopwatch . Stop ( ) ;
87
+ Write ( $ "Breadth-first warm run-through: { stopwatch . Elapsed . TotalMilliseconds } ms ({ stopwatch . Elapsed . TotalSeconds } s).",
88
+ ConsoleColor . Red ) ;
89
+
90
+ // Cold run-through
91
+ tree . EnumerationMode = TreeEnumerationMode . DepthFirst ;
92
+ stopwatch . Restart ( ) ;
93
+ foreach ( var _ in tree )
94
+ {
95
+ }
96
+
97
+ stopwatch . Stop ( ) ;
98
+ Write ( $ "Depth-first cold run-through: { stopwatch . Elapsed . TotalMilliseconds } ms ({ stopwatch . Elapsed . TotalSeconds } s).",
99
+ ConsoleColor . Red ) ;
100
+
101
+ // Warm run-through
102
+ stopwatch . Restart ( ) ;
103
+ foreach ( var _ in tree )
104
+ {
105
+ }
106
+
107
+ stopwatch . Stop ( ) ;
108
+ Write ( $ "Depth-first warm run-through: { stopwatch . Elapsed . TotalMilliseconds } ms ({ stopwatch . Elapsed . TotalSeconds } s).",
109
+ ConsoleColor . Red ) ;
110
+
111
+ // Dump
112
+ stopwatch . Restart ( ) ;
113
+ tree . Dump ( output ) ;
114
+ stopwatch . Stop ( ) ;
115
+
116
+ Performance ( "Text dump write down" , stopwatch . Elapsed ) ;
117
+
118
+ // Serialize
119
+ BinaryFormatter formatter = new ( ) ;
120
+ using ( FileStream fs = new ( Path . Combine ( Environment . CurrentDirectory , "tree.legacybin" ) , FileMode . OpenOrCreate ) )
121
+ {
122
+ stopwatch . Restart ( ) ;
123
+ formatter . Serialize ( fs , tree ) ;
124
+ stopwatch . Stop ( ) ;
125
+ }
126
+
127
+ Performance ( "Legacy binary write down" , stopwatch . Elapsed ) ;
128
+
129
+ stopwatch . Restart ( ) ;
130
+ tree . WriteXml ( Path . Combine ( Environment . CurrentDirectory , "tree.xml" ) ) ;
131
+ stopwatch . Stop ( ) ;
132
+
133
+ Performance ( "XML write down" , stopwatch . Elapsed ) ;
134
+
135
+ stopwatch . Restart ( ) ;
136
+ tree . WriteBinary ( Path . Combine ( Environment . CurrentDirectory , "tree.bin" ) ) ;
137
+ stopwatch . Stop ( ) ;
138
+
139
+ Performance ( "Binary write down" , stopwatch . Elapsed ) ;
140
+
141
+ Console . ReadLine ( ) ;
142
+ Process . Start ( Environment . CurrentDirectory ) ;
143
+ }
144
+ else if ( selection == 2 )
145
+ {
146
+ string file = Path . Combine ( Environment . CurrentDirectory , "tree.legacybin" ) ;
147
+ BinaryFormatter formatter = new ( ) ;
148
+ try
149
+ {
150
+ FileSystemTree fsTree ;
151
+ using ( FileStream fs = new ( file , FileMode . Open ) )
152
+ {
153
+ // Cold run-through
154
+ stopwatch . Start ( ) ;
155
+ fsTree = ( FileSystemTree ) formatter . Deserialize ( fs ) ;
156
+ stopwatch . Stop ( ) ;
157
+
158
+ Performance ( "Legacy binary deserialization cold run-through" , stopwatch . Elapsed ) ;
159
+
160
+ // Warm run-through
161
+ fs . Seek ( 0 , SeekOrigin . Begin ) ;
162
+ stopwatch . Restart ( ) ;
163
+ fsTree = ( FileSystemTree ) formatter . Deserialize ( fs ) ;
164
+ stopwatch . Stop ( ) ;
165
+
166
+ Performance ( "Legacy binary deserialization warm run-through" , stopwatch . Elapsed ) ;
167
+ }
168
+
169
+ if ( iterate )
170
+ {
171
+ Console . ForegroundColor = enumerationMode == TreeEnumerationMode . DepthFirst
172
+ ? ConsoleColor . Cyan
173
+ : ConsoleColor . Green ;
174
+ fsTree . EnumerationMode = enumerationMode ;
175
+ foreach ( var branch in fsTree )
176
+ {
177
+ Console . WriteLine ( branch ) ;
178
+ }
179
+ }
180
+
181
+ Write ( Environment . NewLine ) ;
182
+ }
183
+ catch ( Exception ex )
184
+ {
185
+ Write ( "Error parsing legacy binary file:" , ConsoleColor . Red ) ;
186
+ Write ( ex . Message + ex . StackTrace , ConsoleColor . Red ) ;
187
+ }
188
+
189
+ Write ( Environment . NewLine ) ;
190
+ Console . Read ( ) ;
191
+ }
192
+ else if ( selection == 3 )
193
+ {
194
+ string file = Path . Combine ( Environment . CurrentDirectory , "tree.bin" ) ;
195
+ try
196
+ {
197
+ // Cold run-through
198
+ stopwatch . Start ( ) ;
199
+ FileSystemTree fsTree = Tree . ParseBinary < FileSystemTree > ( file ) ;
200
+ stopwatch . Stop ( ) ;
201
+
202
+ Performance ( "Binary deserialization cold run-through" , stopwatch . Elapsed ) ;
203
+
204
+ // Warm run-through
205
+ stopwatch . Restart ( ) ;
206
+ fsTree = ( FileSystemTree ) Tree < FileSystemTreeBranch > . ParseBinary ( file ) ;
207
+ stopwatch . Stop ( ) ;
208
+
209
+ Performance ( "Binary deserialization warm run-through" , stopwatch . Elapsed ) ;
210
+
211
+ if ( iterate )
212
+ {
213
+ Console . ForegroundColor = enumerationMode == TreeEnumerationMode . DepthFirst
214
+ ? ConsoleColor . Cyan
215
+ : ConsoleColor . Green ;
216
+ fsTree . EnumerationMode = enumerationMode ;
217
+ foreach ( var branch in fsTree )
218
+ {
219
+ Console . WriteLine ( branch ) ;
220
+ }
221
+ }
222
+
223
+ Write ( Environment . NewLine ) ;
224
+ }
225
+ catch ( Exception ex )
226
+ {
227
+ Write ( "Error parsing binary file:" , ConsoleColor . Red ) ;
228
+ Write ( ex . Message + ex . StackTrace , ConsoleColor . Red ) ;
229
+ }
230
+
231
+ Write ( Environment . NewLine ) ;
232
+ Console . Read ( ) ;
233
+ }
234
+ else if ( selection == 4 )
235
+ {
236
+ string file = Path . Combine ( Environment . CurrentDirectory , "tree.xml" ) ;
237
+ try
238
+ {
239
+ // Cold run-through
240
+ stopwatch . Start ( ) ;
241
+ FileSystemTree fsTree = ( FileSystemTree ) Tree . ParseXml ( file ) ;
242
+ stopwatch . Stop ( ) ;
243
+
244
+ Performance ( "XML deserialization cold run-through" , stopwatch . Elapsed ) ;
245
+
246
+ // Warm run-through
247
+ stopwatch . Restart ( ) ;
248
+ fsTree = ( FileSystemTree ) Tree . ParseXml ( file ) ;
249
+ stopwatch . Stop ( ) ;
250
+
251
+ Performance ( "XML deserialization warm run-through" , stopwatch . Elapsed ) ;
252
+
253
+ if ( iterate )
254
+ {
255
+ Console . ForegroundColor = enumerationMode == TreeEnumerationMode . DepthFirst
256
+ ? ConsoleColor . Cyan
257
+ : ConsoleColor . Green ;
258
+ fsTree . EnumerationMode = enumerationMode ;
259
+ foreach ( var branch in fsTree )
260
+ {
261
+ Console . WriteLine ( branch ) ;
262
+ }
263
+ }
264
+
265
+ Write ( Environment . NewLine ) ;
266
+ }
267
+ catch ( Exception ex )
268
+ {
269
+ Write ( "Error parsing XML file:" , ConsoleColor . Red ) ;
270
+ Write ( ex . Message + ex . StackTrace , ConsoleColor . Red ) ;
271
+ }
272
+
273
+ Write ( Environment . NewLine ) ;
274
+ Console . Read ( ) ;
275
+ }
276
+ else if ( selection == 5 )
277
+ {
278
+ iterate = ! iterate ;
279
+ }
280
+ else if ( selection == 6 )
281
+ {
282
+ enumerationMode = enumerationMode == TreeEnumerationMode . DepthFirst
283
+ ? TreeEnumerationMode . BreadthFirst
284
+ : TreeEnumerationMode . DepthFirst ;
285
+ }
286
+ else if ( selection == 7 ) return ;
287
+
288
+ goto EnterSelection ;
289
+
290
+
291
+ static void BuildTree ( DirectoryInfo current , FileSystemTreeBranch branch )
292
+ {
293
+ // Scans the file system structure and builds up the tree
294
+ // The try/catch is necessary for system files as these would fire exceptions
295
+ try
296
+ {
297
+ foreach ( var file in current . GetFiles ( ) )
298
+ branch . AddBranch ( new FileSystemTreeBranch ( file . Name , false ) ) ;
299
+ foreach ( var dir in current . GetDirectories ( ) )
300
+ {
301
+ FileSystemTreeBranch next = new ( dir . Name , true ) ;
302
+ BuildTree ( dir , next ) ;
303
+ branch . AddBranch ( next ) ;
304
+ }
305
+ }
306
+ catch ( UnauthorizedAccessException )
307
+ {
308
+ }
309
+ }
310
+
311
+ static void Write ( string message , ConsoleColor color = ConsoleColor . White )
312
+ {
313
+ Console . ForegroundColor = color ;
314
+ Console . WriteLine ( message ) ;
315
+ }
316
+
317
+ static void Performance ( string name , TimeSpan timing )
318
+ {
319
+ Console . ForegroundColor = ConsoleColor . Magenta ;
320
+ Console . WriteLine ( $ "[PERFORMANCE] { name } : { timing . TotalMilliseconds } ms ({ timing . TotalSeconds } s)") ;
321
+ }
0 commit comments