Console.SetOut to StreamWriter, write to textfile constantly - c#

I'm using the Console.SetOut method to write all my Console.Out.WriteLines to a file, and this works. The only problem is that it only writes everything to the textfile when I close my application instead of it writing whenever a Console.Out.WriteLine happens.
Any ideas on how I can realise this?
How I do it:
Before Application.Run();
FileStream writerOutput = new FileStream("Logging_Admin.txt", FileMode.Append, FileAccess.Write);
StreamWriter writer = new StreamWriter(writerOutput);
Console.SetOut(writer);
After Application.Run():
writer.Dispose();
Thanks.

StreamWriter has an AutoFlush property. When set to true, you should get the result you need.

The StreamWriter will buffer its contents by default. If you want to flush the buffer you must call the Flush method:
Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.

If you don't want to call flush every time manually, you might want to consider implementing your own TextWriter-derived object to do this for you.

To flush the buffer, you can do
writer.Close();

Related

C# FileStream - Reader/Writer on a file, on a per line basis - Flush or FileLock?

I have a StreamWriter with an AutoFlush = true property. However, I still see the file only partially written when I randomly open it. I'm writing a file that needs to be fully written (JSON) or not during any given time.
var sw = new StreamWriter("C:\file.txt", true /* append */, Encoding.ASCII) { AutoFlush = true };
sw.WriteLine("....");
// long running (think like a logging application) -- 1000s of seconds
sw.Close();
In between the sw.WriteLine() call and sw.Close() I want to open the file, and always have it be in the "correct data format", i.e. my line should be complete.
Current Idea:
Increase the internal buffer of FileStream (and/or StreamWriter) to let's say 128KB. Then every 128KB-1, call .Flush() on the FileStream object. This leads me to my next question, when I do call Flush(), should I right before calling it get the Stream.Position and do a File.Lock(Position, 128KB-1)? Or does Flush take care of that?
Basically I don't want the reader to be able to read the contents in between Flush(), because it'll maybe partially broken.
Basically I don't want the reader to be able to read the contents in between Flush(), because it'll maybe partially broken.
I take it you have one open stream.
There is a writer and a reader.
The reader should not read until the flush is completed.
You'll need to use the manual lock mechanism that releases after your flush call.
You can implement in-line or if this is constantly used you can create a thread-safe stream.

StreamWriter even with AutoFlush true leaves lines half written

I have a StreamWriter with an AutoFlush = true property. However, I still see the file only partially written when I randomly open it. I'm writing a file that needs to be fully written (JSON) or not during any given time.
var sw = new StreamWriter("C:\file.txt", true /* append */, Encoding.ASCII) { AutoFlush = true };
sw.WriteLine("....");
// long running (think like a logging application) -- 1000s of seconds
sw.Close();
In between the sw.WriteLine() call and sw.Close() I want to open the file, and always have it be in the "correct data format", i.e. my line should be complete.
Current Idea:
Increase the internal buffer of FileStream (and/or StreamWriter) to let's say 128KB. Then every 128KB-1, call .Flush() on the FileStream object. This leads me to my next question, when I do call Flush(), should I right before calling it get the Stream.Position and do a File.Lock(Position, 128KB-1)? Or does Flush take care of that?
Basically I don't want the reader to be able to read the contents in between Flush(), because it'll maybe partially broken.
using (StreamWriter sw = new StreamWriter("FILEPATH"))
{
sw.WriteLine("contents");
// if you open the file now, you may see partially written lines
// since the sw is still working on it.
}
// access the file now, since the stream writer has been properly closed and disposed.
If you need a "log-like" file which is never half-written, the way to go is not keeping it open.
Every time, you want to write your file, you should instantiate a new FileWriter, which will flush the file contents upon releasing the file like this:
private void LogLikeWrite(string filePath, string contents)
{
using (StreamWriter streamWriter = new StreamWriter(filePath, true)) // the true will make you append to the file instead of overwriting its contents
{
streamWriter.Write(contents);
}
}
This way your write operations will be flushed immediately.
If you are sharing the file between processes, your going to have a race condition unless you produce a locking mechanism of some kind. See https://stackoverflow.com/a/29127380/892327. This does require that you are able to modify both processes.
An alternative is to have process A wait for a file at a specified location. Process B writes to a intermediate file and once B has flushed, the file is copied to the location process A is expecting a file to be so that it can consume the file.

C# - Write Data To A Stream + Read Data With Another Stream

Right now I have a StreamWriter and a StreamReader, 1 file that holds the (text) data, at least 2 threads. 1 thread is a listener and reads the data. The other thread writes stuff into the stream.
Can I avoid using a file as the memory buffer ?
I thought it might be possible to connect the 2 streams from both ends. But dunno how. I create the writer that writes to the file. Then I start a thread that creates a reader that reads from this file and does his work. It works but I want to avoid the file thingy.
// writer
StreamWriter writer = new StreamWriter(new FileStream("text.txt", FileMode.Create, FileAccess.Write, FileShare.Read));
writer.AutoFlush = true;
// reader
StreamReader reader = new StreamReader(new FileStream("text.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
I published something I called ProducerConsumerStream that will do this. It's an in-memory stream that allows one reader and one writer. It's a fixed-size circular buffer that allows a consumer to read as fast as the producer can write. See Building a new type of stream.

Writing to txt file with StreamWriter and FileStream

I ran into something interesting when using a StreamWriter with a FileStream to append text to an existing file in .NET 4.5 (haven't tried any older frameworks). I tried two ways, one worked and one didn't. I'm wondering what the difference between the two is.
Both methods contained the following code at the top
if (!File.Exists(filepath))
using (File.Create(filepath));
I have the creation in a using statement because I've found through personal experience that it's the best way to ensure that the application fully closes the file.
Non-Working Method:
using (FileStream f = new FileStream(filepath, FileMode.Append,FileAccess.Write))
(new StreamWriter(f)).WriteLine("somestring");
With this method nothing ends up being appended to the file.
Working Method:
using (FileStream f = new FileStream(filepath, FileMode.Append,FileAccess.Write))
using (StreamWriter s = new StreamWriter(f))
s.WriteLine("somestring");
I've done a bit of Googling, without quite knowing what to search for, and haven't found anything informative. So, why is it that the anonymous StreamWriter fails where the (non-anonymous? named?) StreamWriter works?
It sounds like you did not flush the stream.
http://msdn.microsoft.com/en-us/library/system.io.stream.flush.aspx
It looks like StreamWriter writes to a buffer before writing to the final destination, in this case, the file. You may also be able to set the AutoFlush property and not have to explicitly flush it.
http://msdn.microsoft.com/en-us/library/system.io.streamwriter.autoflush.aspx
To answer your question, when you use the "using" block, it calls dispose on the StreamWriter, which must in turn call Flush.
The difference between the two code snippets is the use of using. The using statement disposes the object at the end of the block.
A StreamWriter buffers data before writing it to the underlying stream. Disposing the StreamWriter flushes the buffer. If you don't flush the buffer, nothing gets written.
From MSDN:
You must call Close to ensure that all data is correctly written out to the underlying stream.
See also: When should I use “using” blocks in C#?

What happens if StreamReader or StreamWriter are not closed?

I'm working on an assignment for a professor that is strict about LOC. For this reason I'd like to do the following:
(new StreamWriter(saveFileDialog.FileName)).Write(textBox.Text);
instead of
StreamWriter sw = new StreamWriter(saveFileDialog.FileName);
sw.Write(textBox.Text);
sw.Close();
In the first example I don't close the stream. Is this ok? Will it cause any security or memory problems?
You may not get any output, or incomplete output. Closing the writer also flushes it. Rather than manually calling Close at all, I'd use a using statement... but if you're just trying to write text to a file, use a one-shot File.WriteAllText call:
File.WriteAllText(saveFileDialog.FileName, textBox.Text);
Maybe your tutor is looking for:
File.WriteAllText(saveFileDialog.FileName, textbox.Text);
It's reasonable to prefer concise code, but not at the expense of readability or correctness.
Simplest solution without fout.Close() should be:
using (StreamWriter fout = new StreamWriter(saveFileDialog.FileName))
{
fout.Write(textBox.Text);
}
If you don't close it, you can't guarantee that it'll write out the last piece of data written to it. This is because it uses a buffer and the buffer is flushed when you close the stream.
Second, it will lock the file as open preventing another process from using it.
The safest way to use a filestream is with a using statement.
Short answer, the resources allocated for that operation will not be freed not to mention that it could pottentially lock that file.
Consider
using( var fout = new StreamWriter(saveFileDialog.FileName){ fout.write(textBox.Text); }
Any how GC will close it for you. But the thing is until the GC closes that stream you are unnecessary putting on hold to the resources
You can try with using blok in order to clean your no managed object
using (var streamWriter = new StreamWriter(saveFileDialog.FileName))
{
streamWriter.Write(textBox.Text);
}
It would be a memory hazard.
I would always use StreamWriter in a 'using' statement
using(StreamWriter fout = new StreamWriter(saveFileDialog.FileName)
{
fout.Write(textBox.Text);
}

Categories

Resources