C# Overwriting file with StreamWriter created from FileStream
The problem you are having is that reading from the stream advances to the end of the file. Further writes will then append.
This will achieve a full overwrite.
using(FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
{
StreamReader sr = new StreamReader(fs);
using (StreamWriter sw = new StreamWriter(fs))
{
newString = someStringTransformation(sr.ReadToEnd());
// discard the contents of the file by setting the length to 0
fs.SetLength(0);
// write the new content
sw.Write(newString);
}
}
Why use SetLength
? Your new content might be shorter than the existing string! The last thing you want is the old content at the end of your file.
There are several steps you need to take here but let me make my assumptions clear:
You need to keep the file open and locked during the entire operation to prevent others from accessing the file during this time.
With that said, here's what you need to do:
- You need to read the contents using the
StreamReader
, as you've done - You need to reposition the underlying stream back to the start, its position have been changed by reading through the reader
- You need to write out the transformed contents through the
StreamWriter
, as you've done - You need to flush the writer because of the next step
- You need to truncate the underlying stream/file to its current position, to handle a transformation that shortens the contents.
The code for all of this could look like this LINQPad program:
void Main()
{
const string filePath = @"d:\temp\test.txt";
var encoding = Encoding.UTF8;
using (var stream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
using (var reader = new StreamReader(stream, encoding))
using (var writer = new StreamWriter(stream, encoding))
{
// Read
var contents = reader.ReadToEnd();
// Transform
var transformedContents = contents.Substring(0, Math.Max(0, contents.Length - 1));
// Write out transformed contents from the start of the file
stream.Position = 0;
writer.Write(transformedContents);
writer.Flush();
// Truncate
stream.SetLength(stream.Position);
}
}