The above text composers can be used to create well-structured text in terms of indentation, spaces, and contents. In order to create a hierarchy of text files organized as we need the FilesComposer class under the TextComposerLib.Files namespace can be used. The FilesComposer is essentially a dictionary of TextFileComposer objects. Each key in the dictionary is a string that holds a relative path for some text file. The contents of the text file are created in-memory inside the TextFileComposer associated with that key using an internal LinearComposer object. First we need to understand how the TextFileComposer class works then we will explain the FilesComposer class.
The main members of the TextFileComposer class include:
- FilePath : This is a string holding the relative path of the text file. This member is set by the parent FilesComposer object.
- FinalText : This is a string holding the final text of the file.
- TextComposer : This is a LinearComposer object that is used to create the text of the file.
- IsFinalTextReady : This property returns true when the final file text is ready to be used.
- Clear() : This method clears the final text and the internal LinearComposer object.
- FinalizeText() : This method copies the created text from the internal LinearComposer object to the FinalText member and then clears the internal LinearComposer object.
- SaveText() : This method saves the contents of the file to disk.
The work cycle for this class goes as follows:
- When a TextFileComposer object is created the FinalText member contains an empty string, the TextComposer member is internally set to null, and the IsFinalTextReady is true.
- When the TextComposer member is used an internal LinearComposer is created automatically and the IsFinalTextReady is set to false.
- The user can then use the TextComposer member to compose the text as explained earlier.
- When the text is ready a call to FinalizeText() copies the text from the internal LinearComposer object to the FinalText member and sets the IsFinalTextReady to true and resets the internal LinearComposer object to null to preserve memory.
This simple cycle is the base for all the work done by the parent FilesComposer dictionary class. At any instance the FilesComposer can have a single active file that can be accessed using several members of the class. Nevertheless any other file can be accessed at any time by setting the active file of the composer to the selected file and storing a reference to the file externally.
In addition to the usual IDictionary interface methods the FilesComposer class contains useful methods and properties to ease the creation of arbitrary folder structure holding the text files. After the full structure is created it can be saved to disk using the SaveToDisk method or it can be saved to a single text file using the SaveToFile method. Here are some of the most useful of the FilesComposer methods:
- AreAllFilesReady and AreSomeFilesNotReady : Used to test the composer’s files final text.
- PathSeparator : A string acting as a path separator for the files. The default is the “\” string naturally.
- ActiveFileName, ActiveFileComposer, ActiveFileTextComposer, ActiveFileFinalText, ActiveFolder, ActiveFilePath, ActiveFolderLevel, and HasActiveFile : All these members can be used to access properties of the TextFileComposer object of the active file.
- Files, ReadyFiles, NotReadyFiles, FilePaths, and FolderPaths: These properties return information about the files in the FilesComposer.
- FirstFileComposer, FirstFileTextComposer, and FirstFileFinalText : These properties return information about the first file in the FilesComposer dictionary. This is usually used when a single file is to be created.
- SelectFolder() : At any instance of time we can specify an active folder, using this method, for the FilesComposer. The active folder can then be used to create a new (or select an existing) file to be treated as an active file. We can then use the ActiveFileComposer property or other related properties to access the TextFileComposer object associated with the active file.
- DownFolder() : We can use this method to create\select a folder under the active folder given a relative path.
- UpFolder() : We can use this method to select a parent folder of the active folder. We can specify the number of levels to go up the folders chain.
- SelectFile() : We can use this method to select a file under the active folder to be treated as the active file of the FilesComposer. We can also supply an action (a method returning void) that takes the TextFileComposer object of the selected file to perform any required processing on the selected file’s LinearComposer.
- InitalizeFile() : Similar to SelectFile but clears the contents of the file’s TextFileComposer object upon selection.
- UnselectActiveFile() : Sets the active file to null and the HasActiveFile property to false. We can supply an action to be executed on the active file’s TextFileComposer object before un-selecting the file.
- FinalizeAllFiles() : This method calls the FinalizeText() method of all TextFileComposer objects in the FilesComposer class. This ensures all files have ready final text to be saved or read by the user.
- SaveToDisk() : Save all the files contents in the FilesComposer to their appropriate folders on disk given a root path. Other overloaded versions of this method can save all files contents to a single text file or save a single selected file to disk.
The shown code will generate three files inside two folders:
- Inside Folder1 we get File1-1.txt and File1-2.txt
- Inside Folder2 we get File2-1.txt
The contents of the 3 files are as below:
File < Folder1\File1-1.txt > :
Text Inside File1-1.txt
More Text Inside File1-1.txt
File < Folder1\File1-2.txt > :
Text Inside File1-2.txt
File < Folder2\File2-1.txt > :
Text Inside File2-1.txt
In this example after the FilesComposer object is created 4 statements are responsible for filling the files with their contents:
- The first statement selects (i.e. creates and activates) the file File1-1.txt under Folder1. It then uses the ActiveFileComposer property of the FileComposer to add text to File1-1.txt
- The second statement selects (i.e. creates and activates) the file File1-2.txt also under Folder1. It then adds text to the active file composer.
- The third statement switches to another folder and perform similar tasks on a new file File2-1.txt
- The final statement re-selects the file File1-1.txt under Folder1 and adds more text to its composer
var composer = new FilesComposer();
.AppendLine("Text Inside File1-1.txt");
.AppendLine("Text Inside File1-2.txt")
.AppendLine("Text Inside File2-1.txt")
.AppendLine("More Text Inside File1-1.txt")