Background
External sorting refers to the sorting of large files, that is, the records to be sorted are stored in external storage, and files to be sorted cannot be loaded into memory at a time, data exchange between memory and external memory is required multiple times to sort the entire file. The most common algorithm for external sorting is multi-channel Merge Sorting, which breaks down the original file into multiple parts that can be loaded into memory at one time and transfers each part to the memory for sorting. Then, merge and sort the sorted sub-files.
Problem proposal
Suppose we want to write an external sorting program. Now we will discuss how to merge and sort sorted sub-files.
Solution 1
The following is the code snippet of the external sorting and merging phase:
01: class ExternalSorting02: {03: void Merge (string inputFileName1, string inputFileName2, string outputFileName) 04: {05: using (var reader1 = new StreamReader (inputFileName1) 06: {07: using (var reader2 = new StreamReader (inputFileName2) 08: {09: using (var writer = new StreamWriter (outputFileName) 10: {11: Merge (reader1, reader2, writer); 12:} 13:} 14:} 15:} 16: 17: void Merge (TextReader reader1, TextReader reader2, TextWriter writer) 18: {19: var s1 = reader1.ReadLine (); 20: var s2 = reader2.ReadLine (); 21: while (s1! = Null | s2! = Null) 22: {23: if (Compare (s1, s2) <= 0) StepIt (ref s1, reader1, writer); 24: else StepIt (ref s2, reader2, writer); 25 :}26 :}27: 28: int Compare (string s1, string s2) 29: {30: if (s1 = null & s2 = null) throw new ArgumentException ("s1 and s2 cannot be both null"); 31: if (s1 = null) return 1; 32: if (s2 = null) return-1; 33: return string. compare (s1, s2); 34:} 35: 36: void StepIt (ref string s, TextReader reader, TextWriter writer) 37: {38: writer. writeLine (s); 39: s = reader. readLine (); 40:} 41 :}
In the above Code, the three using statements from lines 05th to 14 are nested one by one and indented one by one. Isn't it ugly?
Note: In the above Code, the 33rd lines can replace the method you want to compare the size of the Code to sort by different keywords.
Solution 2
We know that multiple objects can be used with the using statement, but these objects must be declared in the using statement. Therefore, we can refactor the above 05th to 14 lines of code as follows:
1: using (TextReader reader1 = new StreamReader(inputFileName1),2: reader2 = new StreamReader(inputFileName2))3: {4: using (TextWriter writer = new StreamWriter(outputFileName))5: {6: Merge(reader1, reader2, writer);7: }8: }
However, there are two nested using statements, which are not satisfactory.
Solution 3
We also know that the C # compiler actually converts the using statement into a try-finally block. Then we continue to refactor:
01: TextReader reader1 = null;02: TextReader reader2 = null;03: TextWriter writer