String Replace and File Handling library
Library which contains code for replacing some of the Text in files based on conditions and handling the files by reading and writing strings from or to the file by recursively browsing the folder.
- Download library - 5.48 KB
- Download source - 7.9 KB
- Download String Replace sample illustrating TextReplaceIO library usage - 14.12 KB
Introduction
The article is mainly for beginners of .NET programming, who will be in need of creating some UI Tools/Console application for replacing some of the Text in various files based on their needs. I have written a TextReplaceIO
Library, includes DirectoryHandler
and a StringReplaceHelper
class which will be helpful for the purpose of StringReplacement
in a text file based on the user conditions by recursively browsing through the folder. I also created a simple StringReplaceTool
sample using the DirectoryHandler
and StringReplaceHelper
class, where anyone can create a Search and Replace Tool for their needs with very little code. I didn't get more time to spend on the sample, to make it better, and illustrate all the functionality. However, if anyone needs a specific sample for explaining any functionality, please email me.
Background
During my earlier development on Custom controls, and Website Development, I came across many situations where I was in need of replacing the version numbers during each build performed. So, I thought of having a library which will help to handle such scenarios (However, I haven't used or tested this library in more scenarios now).
Using the Code
About TextReplaceIO Namespace
The namespace consists of two classes, one for handling the operations on files and folder and another for replacing string
s in various conditions.
DirectoryHandler
This class is used for handling the following operations on files and folders:
-
Reading text files as
string
. The below method is used for this purpose:/// <summary> /// Read the contents of the specified file and return it as a string. /// </summary> /// <remarks> /// If you try to read unsupported file types, and then save the /// file, some files might get corrupted. so make sure to only ///open and write supported files. /// </remarks> /// <param name=""nextFile"">File that needs to be read</param> public string ReadFileContents(FileInfo nextFile) { // updating the variable about the file that is reading. this.processingFileInFo = nextFile; FileStream fs = new FileStream(nextFile.FullName, FileMode.OpenOrCreate, FileAccess.ReadWrite); StreamReader sr = new StreamReader(fs); String fileString = sr.ReadToEnd(); sr.Close(); fs.Close(); return fileString; }
-
Writing
string
to text files. The following method is used for this purpose:/// <summary> /// Write the string contents to a text file. /// </summary> /// <param name=""strWrite"">string to be written on the file</param> /// <param name=""filePath"">Path in which the string has to be written as a file /// </param> /// <param name=""fileMode""><see cref="FileMode"" /></param> public void WriteContentsToFile (string strWrite, string filePath, FileMode fileMode) { String newFileString = strWrite; FileStream fs = new FileStream(filePath, fileMode, FileAccess.Write); StreamWriter sw = new StreamWriter(fs); sw.Write(newFileString); sw.Close(); fs.Close(); }
-
Populate a
treeview
with System drives and load sub nodes on demand. (Actually, I got some core ideas from some other article, but am not able to find it now.). In theDirectoryHandler
class, you have to useCreateTreeViewDirectory(TreeView treeView)
for loading the drives into theTreeNode
. A special folder Desktop type is added in the list, as it is a commonly used special folder. You need to call the following method in theBeforeExpand
event of 'Treeview
' for loading thetreeview
nodes on demand.LoadDirectoryinTreeViewOnDemand(TreeNode parentNode)
method is added in theDirectoryHandler
as many developers like to do their file/folder operations by selecting from atreeview
. -
Parse through all files and folders recursively based on filter conditions, and get the files using the
ManipulateFilteredFile
event.
The following methods are used for this:/// <summary> /// Parse through all the folders in the specified directory /// </summary> /// <param name=""dirInfo"">Provide the directory which needs to be parsed</param> /// <param name=""recursive"">Setting this to 'True' /// will parse through all the subfolders in the directory.</param> public void ParseFolder(DirectoryInfo dirInfo, bool recursive) { DirectoryInfo[] subDirs; FileInfo[] files; ResetOriginal(); //Getting filelist of parent directory ListContentsOfFolder(dirInfo); foreach (DirectoryInfo directory in dirInfo.GetDirectories()) { if (directory != null && directory.Exists) { this.dirCount += 1; subDirs = directory.GetDirectories(); files=directory.GetFiles(); if (recursive && subDirs.Length != 0) { //Getting file list of SubDirectories. ListContentsOfFolder(directory); ParseSubFolder(directory, true); } else if (recursive && files.Length > 0) { //Getting file list of SubDirectories. ListContentsOfFolder(directory); } } } } /// <summary> /// Parse through the contents of each folders /// </summary> /// <param name=""Parent""></param> protected void ListContentsOfFolder(DirectoryInfo Parent) { foreach (FileInfo NextFile in Parent.GetFiles()) { this.fileCount += 1; if (this.FilteredFileTypes == null&& this.FilterFileNames==null) { this.filterFileCount += 1; OnManipulateFilteredFile(NextFile); } else { bool filteredFile = CheckForFilter(NextFile); if (filteredFile) { this.filterFileCount += 1; OnManipulateFilteredFile(NextFile); } } } } /// <summary> /// Raises the ManipulateFilteredFile event. /// </summary> /// <param name=""NextFile"">FileInfo</param> public virtual void OnManipulateFilteredFile(FileInfo NextFile) { ManipulateFilteredFile(this, NextFile); }
-
The
ChangeEvents
method is used for creating log files if a folder or file is changed, deleted or modified. Set theLogFileName
property, in which the log files need to be written./// <summary> /// Updates if there are any changes in the files in the specified directory. /// The changes will be appended to the file, if you set the LogFileName Property. /// </summary> /// <remarks>The User needs to create/clean the log file before he uses these /// events based on the needs as the contents are only appended using this approach /// </remarks> /// <param name=""fsw"">The Folder that needs to be watched for changes</param> public void ChangeEvents(FileSystemWatcher fsw, bool enableRaisingEvents) { fsw.Changed += new FileSystemEventHandler(fsw_Changed); fsw.Deleted += new FileSystemEventHandler(fsw_Deleted); fsw.Created += new FileSystemEventHandler(fsw_Created); fsw.Renamed += new RenamedEventHandler(fsw_Renamed); fsw.EnableRaisingEvents = true; } void fsw_Renamed(object sender, RenamedEventArgs e) { WriteContentsToFile(String.Format("\r\nRenamed {0} to {1}", e.OldName, e.Name), this.LogFileName, FileMode.Append); } ……………………….. …………………………….
StringReplaceHelper
This class is used for replacing String
based on the following conditions:
- Find a specific
string
and replace it with anotherstring
- Find a specific
string
and replace it with anotherstring
, if thestring
s are in between a specified block - Replace entire
string
within a specifiedstring
- Replace the entire
string
within a specifiedstring
if thestring
s are in between a specified block - Replace a
string
if and only if it is found before or after a specificstring
All the above conditions, except (4) are implemented in ReplaceStringWithCondition
method (i.e., a function call will be done in this method, in which based on the parameters, the ReplaceStringWithCondition
function will be executed) and (4) is implemented in the ReplaceStringBetweenWithCondition
method. For now, I have used two different types of logic to get the string
s that need to be searched for replace conditions in each of the above mentioned methods. By further modification, this can be further simplified. I will try to do it later if I get some time to spend on this:
- In
ReplaceStringWithCondition
, I used the inbuiltstring.split
method to split the entirestring
based upon theStartWith
orEndsWith string
as the Tokenizer, and then after modifying thestring
, I will merge the Tokenizers also along with thestring
s. - In
ReplaceStringBetweenWithCondition
to get thestring
that needs to be checked for replacing some of the contents in it, I have split by finding the index of the providedstring
block.
About StringReplaceSample
The sample explains almost all the functionalities of the TextReplaceIO
library, which is mentioned in the TextReplaceIO
section. You can use only some of the methods in your console application or any other application based on your need. Use the sample in the following way. See the code inside the sample for you to get more ideas on the implementations.
Step1
Select the File/Folder, from the Treeview
, in which you want some of the string
s of some files inside the directory that need to be replaced.

Step2
Provide the Filter condition of files that needs to be searched either by giving FileName
or by Filetype
or both.

Step3
Then based upon the condition to replace, fill the Textbox
es and click the corresponding button for required operations:
- For simply replacing some
string
in all the Filtered files, specify the "String to be replaced" and "Replace With" TextBox and click replace. - For replacing some
string
in the entire filtered file, whereas, thestring
is found in between specifiedstring
s, provide 'StartSearch
' and 'EndSearch
': - For replacing a
string
found anywhere before a specifiedstring
, provide 'StartSearch
'TextBox
alone, and click on the button. - For Inserting/Replace entire
string
within someString
s, follow the below steps:- It is essential to provide
String
replace withTextBox
, in the "General String Replacement Group" - Specify '
StartString
' and 'EndString
'TextBox
. - Click on the
Button
below thistextbox
es, so that the contents within theStartString
andEndString
will be replaced.
- It is essential to provide
- For Inserting/Replace entire
string
if it is available within specifiedstring
blocks.- Along with the Steps in Operation(4), include the
StartBlock
and 'EndBlock
', then click the button. - Inserting some
string
in the top or bottom of the file is achieved by using the following code in the sample using thestring.insert
method. The modifiedstring
is written into the file using theWriteContentsToFile
Method, which is called inside theReplaceStringandWriteToFile
method.
Conclusion
I'm sure some of the Regex programmers are going to have a better way, some others might use the StringBuilder
class for this to be done for performance reasons. But, I hope someone will find my program useful. As there are possibilities for adding a lot more extended functionality, if you are in need of any such functionality or code changes for some reason, please feel free to contact me, so that I can add those. Thanks for reading.