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:
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 string
s are in between a specified block - Replace entire
string
within a specified string
- Replace the entire
string
within a specified string
if the string
s 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 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 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 string
s. - 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 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, the string
is found in between specified string
s, 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 String
s, 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 textbox
es, 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.
I am a software developer from Chennai, India. From Novemeber 2004, I am in to the .NET Framework and I enjoy writing codes in C#. My experience in .NET Technology includes designing and creating custom controls and application for Web and windows platform.