Consider:
public static void ConvertFileToUnicode1252(string filePath, Encoding srcEncoding)
{
try
{
StreamReader fileStream = new StreamReader(filePath);
Encoding targetEncoding = Encoding.GetEncoding(1252);
string fileContent = fileStream.ReadToEnd();
fileStream.Close();
// Saving file as ANSI 1252
Byte[] srcBytes = srcEncoding.GetBytes(fileContent);
Byte[] ansiBytes = Encoding.Convert(srcEncoding, targetEncoding, srcBytes);
string ansiContent = targetEncoding.GetString(ansiBytes);
// Now writes contents to file again
StreamWriter ansiWriter = new StreamWriter(filePath, false);
ansiWriter.Write(ansiContent);
ansiWriter.Close();
//TODO -- log success details
}
catch (Exception e)
{
throw e;
// TODO -- log failure details
}
}
The above piece of code returns an out-of-memory exception for large files and only works for small-sized files.
Try this:
Might have some syntax errors as I've done it from memory but this is how I work with large files, read in a chunk at a time, do some processing and save the chunk back. It's really the only way of doing it (streaming) without relying on massive IO overhead of reading everything and huge RAM consumption of storing it all, converting it all in memory and then saving it all back.
You can always adjust the buffer size.
If you want your old method to work without throwing the
OutOfMemoryException
, you need to tell the Garbage Collector to allow very large objects.In App.config, under
<runtime>
add this following line (you shouldn't need it with my code but it's worth knowing):Don't readToEnd and read it like line by line or X characters at a time. If you read to end, you put your whole file into the buffer at once.
I think still using a
StreamReader
and aStreamWriter
but reading blocks of characters instead of all at once or line by line is the most elegant solution. It doesn't arbitrarily assume the file consists of lines of manageable length, and it also doesn't break with multi-byte character encodings.(I wish
StreamReader
had aCopyTo
method likeStream
does, if it had, this would be essentially a one-liner!)