Writing a Text File in memory and saving it with savefiledialog - c#

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.

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());

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.

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());

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.

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.

Related

OpenFileDialog reads only the first file

I'm using the following code to open multiple XML files and read the contents of the files but it doesn't work.
OpenFD.Filter = "XML Files (*.xml)|*.xml";
OpenFD.Multiselect = true;
if (OpenFD.ShowDialog() == DialogResult.OK)
{
foreach (string file in OpenFD.FileNames)
{
MessageBox.Show(file);
System.IO.Stream fileStream = OpenFD.OpenFile();
System.IO.StreamReader streamReader = new System.IO.StreamReader(fileStream);
using (streamReader)
{
MessageBox.Show(streamReader.ReadToEnd());
}
fileStream.Close();
}
}
For testing purposes, I created two xml files.
file1.xml (its content is "string1")
file2.xml (its content is "string2")
When I open the dialog and select the two files, I get four messages.
file1.xml
string1
file2.xml
string1
Even though the OpenFileDialog reads the file names correctly, I can't get to read the second file. It only reads the first file. So I'm guessing the problem is related to StreamReader, not to OpenFileDialog. What am I doing wrong?
You're using OpenFD.OpenFile() in each iteration, which:
Opens the file selected by the user, [...] specified by the FileName property.
Which in turn:
can only be the name of one selected file.
Use the file variable from your loop instead, and the StreamReader constructor that accepts a string:
using (var streamReader = new System.IO.StreamReader(file))
{
MessageBox.Show(streamReader.ReadToEnd());
}
This line is opening the file from the OpenFileDialog:
System.IO.Stream fileStream = OpenFD.OpenFile();
But there's no specification for which file. You need a way to distinguish which file you're opening. I would get rid of that line all together and just use the string file you have in the loop.
System.IO.StreamReader streamReader = new System.IO.StreamReader(file);

How can I write and read a text doucument in a folder?

string curetn = Environment.CurrentDirectory;
string path = curetn.ToString() + #"\DATA\SaveGame.txt";
Console.WriteLine(path);
TextReader tr = new StreamReader(path);
Hello, I am making a text-adventure, and I do not like having all my save files, and mp3 file in the same place as my application. I would like for the files to be in a folder. I want to be able to use StreamWriter and StreamReader, to be able to write and read files that are in a folder. This file is also in a distributable folder, not just in the Visual Studios Projects folders. I have tried everything I can, and this is what I have. I also have one of these for StreamWriter. Please help!
Edit:
The thing that does not work, is that it does not read the lines, and assigns them to a variable. I have it in a try-catch, and it catches, and displays the error message that I wrote.
If you are looking for simply read and write lines from file you can try this
using (StreamReader sr = new StreamReader(path))
{
while (!sr.EndOfStream)
{
sr.ReadLine();
}
}
string s;
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine(s);
}
So basically what you want to do is read the text file:
string data[] = File.ReadAllLines(path); // Read the text file.
var x = data[1]; // Replace the '1' with the line number you want.
Console.WriteLine(x);
This is a good way to read the text file, I think it's better than opening a stream.
You can also write to it, so every time you want to save, just do this:
// When you want to write:
File.WriteAllText(path, "");
File.AppendAllText(path, "Add a data line" + Environment.NewLine); // Environment.NewLine adds a line.
Keep appending text to the file for the data you need.

Create and write file txt

How can I create and then modify writing on this file?
string fileName = #"C:\...\MioFile.txt";
In main:
File.CreateText(fileName);
Then when I would edit the file by adding text.
StreamWriter writer = new StreamWriter(fileName);
sw.WriteLine("Hello"+variable);
sw.Close();
But the file is empty and I cannot write anything.
I would like create a file.txt and I would like for this file to always add new information every time I call it in writing mode. A kind of "log file".
Use File.AppendAllText instead of StreamWriter. Its simple:
File.AppendAllText(filename, "Hello"+variable);
You have sw.WriteLine, But your streamwriter is called "writer". That might be the problem.
I like to use the "using" statements:
//full path
var fileName = #"C:\Users\...\Desktop\newFile2.txt";
//Get the stream in FileMode.Append (will create or open)
using (var fileStream = new FileStream(fileName,FileMode.Append))
{
//pass the fileStream into the writer.
using (var writer = new StreamWriter(fileStream))
{
writer.WriteLine("{0} => file appended", DateTime.Now);
}//dispose writer
}//dispose fileStream

Sharing violation during save as on Ubuntu Linux

I'm new to C# and I'm having a bit of an issue when saving to a new file. My program has two options for saving: save & save as.
I was getting a sharing violation error when saving, but I fixed that by closing the previous filestream. However, I still cant figure out why my save as code is giving me a sharing violation error.
Here's the code:
// get a file stream from the file chooser
FileStream file = File.OpenWrite(saveFc.Filename);
// check to see if the file is Ok
bool fileOk = file.CanWrite;
if (fileOk == true)
{
// get the filename
string filename = file.Name;
// store the filename for later use
UtilityClass.filename = filename;
// get the text from textview1
string text = textview1.Buffer.Text;
// get a StreamWriter
StreamWriter writer = File.CreateText(filename);
// write to the file
writer.Write(text);
// close/save the file
writer.Close();
file.Close();
}
}
// close the file c
If you could help me figure it out that would be much appreciated. Thanks!
You're opening the same file twice:
FileStream file = File.OpenWrite(saveFc.Filename);
And:
string filename = file.Name;
StreamWriter writer = File.CreateText(filename);
Your code could probably be simplified to:
using (var writer = File.CreateText(saveFc.Filename))
{
// store the filename for later use
UtilityClass.filename = saveFc.Filename;
// get the text from textview1
string text = textview1.Buffer.Text;
// write the text
writer.Write(text);
}
If you open the file with CreateText/OpenWrite it will always be writeable (or an exception will be thrown). The using block will automatically close the writer when it exits.

Formatting a text file, how to update the file after I finished parsing it?

How would I open a file, perform some regex on the file, and then save the file?
I know I can open a file, read line by line, but how would I update the actual contents of a file and then save the file?
The following approach would work regardless of file size, and will also not corrupt the original file in anyway if the operation would fail before it is complete:
string inputFile = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments), "temp.txt");
string outputFile = Path.Combine(Environment.GetFolderPath(
Environment.SpecialFolder.MyDocuments), "temp2.txt");
using (StreamReader input = File.OpenText(inputFile))
using (Stream output = File.OpenWrite(outputFile))
using (StreamWriter writer = new StreamWriter(output))
{
while (!input.EndOfStream)
{
// read line
string line = input.ReadLine();
// process line in some way
// write the file to temp file
writer.WriteLine(line);
}
}
File.Delete(inputFile); // delete original file
File.Move(outputFile, inputFile); // rename temp file to original file name
string[] lines = File.ReadAllLines(path);
string[] transformedLines = lines.Select(s => Transform(s)).ToArray();
File.WriteAllLines(path, transformedLines);
Here, for example, Transform is
public static string Transform(string s) {
return s.Substring(0, 1) + Char.ToUpper(s[1]) + s.Substring(2);
}
Open the file for read. Read all the contents of the file into memory. Close the file. Open the file for write. Write all contents to the file. Close the file.
Alternatively, if the file is very large:
Open fileA for read. Open a new file (fileB) for write. Process each line of fileA and save to fileB. Close fileA. Close fileB. Delete fileA. Rename fileB to fileA.
Close the file after you finish reading it
Reopen the file for write
Write back the new contents

Categories