/// <summary> /// Sorts the integers found in an input file and writes the sorted integers to an output file /// </summary> /// <param name="options">The command line options</param> private static List <string> SortIntegers(CommandLineOptions options) { IFileIO fileIO = serviceProvider.GetService <IFileIO>(); IIntegerFileInfoCollector integerFileInfoCollector = serviceProvider.GetService <IIntegerFileInfoCollector>(); //Find the output directory where the output file will be written string outputDirectory = fileIO.GetDirectoryFromFilePath(options.OutputFilePath); //Indicate to the user that we are retrieving information regarding the input file. This can take a long //time for very large files. DisplayInputFileInfoInProgress(); //Collect information on the input file IntegerFileInfo inputFileInfo = integerFileInfoCollector.GetIntegerFileInfo(options.InputFile, (int)options.ChunkSize); //Store the intermediate files so that they can be deleted later on List <string> intermediateFilePaths = new List <string>(); List <string> chunkFiles = CreateChunkFiles(options, inputFileInfo, outputDirectory); //Translate the file names to file paths var chunkFilePaths = chunkFiles.Select(file => Path.Combine(outputDirectory, file)).ToList(); intermediateFilePaths.AddRange(chunkFilePaths); List <string> mergeIntermediateFilePaths = MergeChunkFiles(chunkFiles, options, inputFileInfo); intermediateFilePaths.AddRange(mergeIntermediateFilePaths); return(intermediateFilePaths); }
/// <summary> /// Merges a set of chunk files into a single output file /// </summary> /// <param name="chunkFiles">The chunk files to be merged</param> /// <param name="options">The command line options</param> /// <param name="inputFileInfo">Information regarding the input file</param> /// <returns>The intermediate files that were created while merging</returns> private static List <string> MergeChunkFiles(List <string> chunkFiles, CommandLineOptions options, IntegerFileInfo inputFileInfo) { List <string> intermediateFilePaths = new List <string>(); IFileIO fileIO = serviceProvider.GetService <IFileIO>(); IChunkFileMerger chunkFileMerger = serviceProvider.GetService <IChunkFileMerger>(); //Find the output directory where the output file will be written string outputDirectory = fileIO.GetDirectoryFromFilePath(options.OutputFilePath); //Convert the chunk file names into chunk file paths List <string> chunkFilePaths = chunkFiles .Select(chunkFileName => Path.Combine(outputDirectory, chunkFileName)) .ToList(); //Keep a dictionary of progress bars where the key is the merge generation number, and //the value is the progress bar for that merge generation Dictionary <int, ProgressBar> mergeProgressBars = new Dictionary <int, ProgressBar>(); Action <int, int> updateMergeProgress = (int gen, int integersProcessed) => { if (!mergeProgressBars.ContainsKey(gen)) { //Create a progress bar for the current generation mergeProgressBars[gen] = CreateProgressBar(inputFileInfo.NumOfIntegers, string.Format(MergeProgressMessage, gen - 1)); } bool stepsComplete = UpdateProgressBar(mergeProgressBars[gen], integersProcessed); if (stepsComplete) { OnProgressBarCompleted(); //Display the results of the merge operation. We can calculate the number of output //files that will result from each merge generation int mergedFilesCount = CalculateNumberOfGenerationOutputFiles(chunkFiles.Count, MergeCount, gen - FirstMergeGeneration + 1); DisplayGenMergeResults(gen, mergedFilesCount); } }; List <string> mergeFiles = chunkFileMerger.MergeChunkFilesIntoSingleFile(chunkFilePaths, MergeCount, GenFileTemplate, Path.GetFileName(options.OutputFilePath), outputDirectory, FirstMergeGeneration, !options.KeepIntermediate, updateMergeProgress); intermediateFilePaths.AddRange(mergeFiles); return(intermediateFilePaths); }
/// <see cref="IIntegerFileCreator.CreateIntegerTextFile(IEnumerable{int}, string)"/> public void CreateIntegerTextFile(IEnumerable <int> integers, string filePath) { //Create the directory the file will be living in, if it does not already exist fileIO.CreateDirectory(fileIO.GetDirectoryFromFilePath(filePath)); //Create the file using (Stream fileStream = fileIO.CreateFile(filePath)) { //Create a stream writer from the file stream using (StreamWriter fileStreamWriter = new StreamWriter(fileStream)) { //Iterate over each integer and write it to the file foreach (int integer in integers) { fileIO.WriteIntegerToStream(fileStreamWriter, integer); } //Flush the stream writer fileStreamWriter.Flush(); } } }