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 strings 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:
public string ReadFileContents(FileInfo nextFile)
{
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:
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 the DirectoryHandler class, you have to use CreateTreeViewDirectory(TreeView treeView) for loading the drives into the TreeNode. 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 the BeforeExpand event of 'Treeview' for loading the treeview nodes on demand. LoadDirectoryinTreeViewOnDemand(TreeNode parentNode) method is added in the DirectoryHandler as many developers like to do their file/folder operations by selecting from a treeview.
-
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:
public void ParseFolder(DirectoryInfo dirInfo, bool recursive)
{
DirectoryInfo[] subDirs;
FileInfo[] files;
ResetOriginal();
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)
{
ListContentsOfFolder(directory);
ParseSubFolder(directory, true);
}
else if (recursive && files.Length > 0)
{
ListContentsOfFolder(directory);
}
}
}
}
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);
}
}
}
}
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 the LogFileName property, in which the log files need to be written.
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 another string
- Find a specific
string and replace it with another string, if the strings are in between a specified block
- Replace entire
string within a specified string
- Replace the entire
string within a specified string if the strings are in between a specified block
- Replace a
string if and only if it is found before or after a specific string
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 strings 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 inbuilt string.split method to split the entire string based upon the StartWith or EndsWith string as the Tokenizer, and then after modifying the string, I will merge the Tokenizers also along with the strings.
- In
ReplaceStringBetweenWithCondition to get the string that needs to be checked for replacing some of the contents in it, I have split by finding the index of the provided string 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 strings 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 Textboxes 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, the string is found in between specified strings, provide 'StartSearch' and 'EndSearch':

- For replacing a
string found anywhere before a specified string, provide 'StartSearch' TextBox alone, and click on the button.
- For Inserting/Replace entire
string within some Strings, follow the below steps:
- It is essential to provide
String replace with TextBox, in the "General String Replacement Group"
- Specify '
StartString' and 'EndString' TextBox.
- Click on the
Button below this textboxes, so that the contents within the StartString and EndString will be replaced.

- For Inserting/Replace entire
string if it is available within specified string 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 the string.insert method. The modified string is written into the file using the WriteContentsToFile Method, which is called inside the ReplaceStringandWriteToFile 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.