Replacing Characters in Text Files with .NET
Posted: (EET/GMT+2)
Replacing Characters in Text Files with .NET
Jul 29, 2002
C# and .NET Framework
Being able to load a text file, replace some characters and then save the file back are common requirements for many programs. For instance, we at WhirlWater were required to prettify a basic DIR listing. For your enjoyment, we decided to take the challenge and use C# and .NET Framework for the task.
If you run the basic dir command from the command line and redirect the results to a file, the results are perfect except for one small thing: the space characters to separate thousands in certain numbers are shown as ÿ's when the file is opened in Notepad, like this:
Volume in drive C is SYSTEM
Volume Serial Number is 2B14-3640
Directory of C:\
16.01.2002 11:08 <DIR> WINDOWS
0 File(s) 0 bytes
1 Dir(s) 18ÿ935ÿ856ÿ128 bytes free
Since changing the Windows regional settings or upgrading the operating system to something newer than Windows 2000 wasn't an option for us, we had to use an alternative solution. And that alternative solution was a little utility application.
Streams and string buffers
If you have done any development with files in .NET, you know that stream objects are what you need to read a file. In .NET, there are many different stream objects to choose from. There are also objects named StreamReader and StreamWriter, which proved to be just perfect for our needs.
Our application is a command line application that takes a single parameter that designates the file to process. For the most important parts, the code looks like this:
using System;
using System.IO;
using System.Text;
static int Main(string[] args)
{
// test if there are any command line parameters
if (args.Length == 0)
{
Console.WriteLine("FixDirListing: Expected a filename as parameter.");
Console.WriteLine("Usage: FIXDIRLISTING.exe [filename]");
return 1;
}
try
{
// read the filename from the command line
int startTime = Environment.TickCount;
string fileName = args[0];
Console.Write("Fixing file \""+fileName+"\".");
StreamReader sr = new StreamReader(fileName,Encoding.ASCII);
StringBuilder sb = new StringBuilder(sr.ReadToEnd());
sr.Close();
Console.Write(".");
// replace all characters in the string and
// write data back to file
sb.Replace('\x3F','\x20'); // "�" -> " "
Console.Write(".");
StreamWriter sw = new StreamWriter(fileName,false,
Encoding.ASCII);
sw.Write(sb.ToString());
sw.Close();
Console.WriteLine(".");
int endTime = Environment.TickCount;
// done!
Console.WriteLine("Dir listing fixed OK in "+
(endTime-startTime)+" ms.");
return 0;
}
catch (Exception e)
{
Console.WriteLine("FixDirListing: "+e.ToString());
return 2;
}
}
At first, the code reads the given file into a StreamReader object. Then, it instantiates a StringBuilder object that is used to manipulate the file data. Since the StringBuilder is a mutable object meaning that it can be modified in place (as opposed to a String), calling the Replace method is really fast.
It is also worth noting how the Environment.TickCount method is used to save the start and end times of the operation. We should note that .NET is really fast: a 10-megabyte text file was processed in less than two seconds on an average Pentium III computer. So, the output could look like this:
Fixing file "C:\Temp\File List.txt".... Dir listing fixed OK in 160 ms.
Probably you could tweak the code some more, but we are satisfied with the current situation.
Download the example code
Download replacingcharactersintextfiles.zip (10 kB) which contains the sample application presented in this article. Please note that the sample application will require Visual Studio .NET to be installed to compile.
* * *
Do you need consulting help to kick your .NET project into higher gear? Let us help!