Writing a Text File in memory and saving it with savefiledialog

42.8k Views Asked by At

I am trying to make a text file in memory, add some lines to it and at the end save the file in a text file. I can handle the savedialog part but I dont know how to get the text file from memory. Any help and tips will be appriciated.

What I am doing so far is:

//Initialize in memory text writer
MemoryStream ms = new MemoryStream(); 
TextWriter tw = new StreamWriter(ms);

tw.WriteLine("HELLO WORLD!");
tw.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!);

please note I will call tw.WriteLine() add more lines in different places so I want to save this at end of program (so this shouldent be wrapped between something like using{} )

UPDATE

StringBuilder seems to be a more reliable option for doing this! I get strange cut-outs in my text file when I do it using MemoryStream.

Thanks.

5

There are 5 best solutions below

5
On BEST ANSWER

I think your best option here would be to write to a StringBuilder, and when done, File.WriteAllText. If the contents are large, you might consider writing directly to the file in the first place (via File.CreateText(path)), but for small-to-medium files this should be fine.

var sb = new StringBuilder();

sb.AppendLine("HELLO WORLD!");
sb.AppendLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!");

File.WriteAllText(path, sb.ToString());
4
On

Assume your SaveFileDialog name is "dialog"

File.WriteAllBytes(dialog.FileName, Encoding.UTF8.GetBytes("Your string"));

or

var text = "Your string";
text += "some other text";
File.WriteAllText(dialog.FileName, text);

also in your own solution you can do this :

MemoryStream ms = new MemoryStream(); 
TextWriter tw = new StreamWriter(ms);

tw.WriteLine("HELLO WORLD!");
tw.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!);

// just add this
File.WriteAllBytes(dialog.FileName, ms.GetBuffer());
2
On

Something like this.

Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".text"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension

// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();

// Process save file dialog box results
if (result == true)
{
    // Save document
    using (FileStream file = File.CreateText(dlg.FileName)
    {
        ms.WriteTo(file)
    }
}

I haven't worried about whether the file already exists but this should get you close.

You might need a ms.Seek(SeekOrgin.Begin, 0) too.

3
On

Or, something nigh-on the same as @Marc's answer, but different enough that I think it's worth putting out there as a valid solution:

using (var writer = new StringWriter())
{
    writer.WriteLine("HELLO WORLD!");
    writer.WriteLine("I WANT TO SAVE THIS FILE AS A .TXT FILE!");
    File.WriteAllLines(path, writer.GetStringBuilder().ToString());
}

Where path is a string representing a valid file system entry path, predefined by you somewhere in the application.

0
On

Another way of appending text to the end of a file could be:

if (saveFileDialog.ShowDialog() == DialogResult.OK) {
    using (var writer = new StreamWriter(saveFileDialog.Filename, true)) {
        writer.WriteLine(text);
    }
}

supposing that text is the string you need to save into your file. If you want to append new lines to that string in an easy way, you can do:

var sb = new StringBuilder();
sb.AppendLine("Line 1");
sb.AppendLine("Line 2");

and the resulting string will be sb.ToString()

If you already have a Stream object (in your example, a MemoryStream), you can do the same but replace the line:

using (var writer = new StreamWriter(saveFileDialog.Filename, true)) {

by

using (var writer = new StreamWriter(memoryStream)) {

Edit:
About wrapping the statements inside using:

Take in count that this is not a problem at all. In my first example, all you will have to do is to keep that StringBuilder object, and keep adding lines to it. Once you have what you want, just write the data into a text file.

If you are planning to write more than once to the text file, just clear the StringBuilder everytime you write, in order to not get duplicated data.