streamWriter rewrite the file or append to the file - c#

I am using this
for($number=0; $number < 5; $number++){
StreamWriter x = new StreamWriter("C:\\test.txt");
x.WriteLine(number);
x.Close();
}
if something is in test.text, this code will not overwrite it. I have 2 questions
1: how can I make it overwrite the file
2: how can I append to the same file
using C#

Try the FileMode enumerator:
FileStream fappend = File.Open("C:\\test.txt", FileMode.Append); // will append to end of file
FileStream fcreate = File.Open("C:\\test.txt", FileMode.Create); // will create the file or overwrite it if it already exists

StreamWriters default behavior is to create a new file, or overwrite it if it exists. To append to the file you'll need to use the overload that accepts a boolean and set that to true. In your example code, you will rewrite test.txt 5 times.
using(var sw = new StreamWriter(#"c:\test.txt", true))
{
for(int x = 0; x < 5; x++)
{
sw.WriteLine(x);
}
}

You can pass a second parameter to StreamWriter to enable or disable appending to file:
in C#.Net:
using System.IO;
// This will enable appending to file.
StreamWriter stream = new StreamWriter("YourFilePath", true);
// This is default mode, not append to file and create a new file.
StreamWriter stream = new StreamWriter("YourFilePath", false);
// or
StreamWriter stream = new StreamWriter("YourFilePath");
in C++.Net(C++/CLI):
using namespace System::IO;
// This will enable appending to file.
StreamWriter^ stream = gcnew StreamWriter("YourFilePath", true);
// This is default mode, not append to file and create a new file.
StreamWriter^ stream = gcnew StreamWriter("YourFilePath", false);
// or
StreamWriter^ stream = gcnew StreamWriter("YourFilePath");

You can start by using the FileStream and then passing that to your StreamWriter.
FileStream fsOverwrite = new FileStream("C:\\test.txt", FileMode.Create);
StreamWriter swOverwrite = new StreamWriter(fsOverwrite);
or
FileStream fsAppend = new FileStream("C:\\test.txt", FileMode.Append);
StreamWriter swAppend = new StreamWriter(fsAppend);

So what is the result of your code?
I would expect the file to contain nothing but the number 4, since the default behavior is to create/overwrite, but you are saying that it is not overwriting?
You should be able to make it overwrite the file by doing what you are doing, and you can append by making a FileStream with FileMode.Append.

Related

C# Spire Document.SaveToStream not working

I have the following code but it is just creating a 0kb empty file.
using (var stream1 = new MemoryStream())
{
MemoryStream txtStream = new MemoryStream();
Document document = new Document();
fileInformation.Stream.CopyTo(stream1);
document.LoadFromStream(stream1, FileFormat.Auto);
document.SaveToStream(txtStream, FileFormat.Txt);
StreamReader reader = new StreamReader(txtStream);
string text = reader.ReadToEnd();
System.IO.File.WriteAllText(fileName + ".txt", text);
}
I know the data is successfully loaded into document because if do document.SaveToTxt("test.txt", Encoding.UTF8);
instead of the SaveToStream line it exports the file properly.
What am I doing wrong?
When copying a stream, you need to take care to reset the position to 0 if copying. As seen in the answer here, you can do something like this to your streams:
stream1.Position = 0;
txtStream.Position = 0;

C# Text Writer writes at the start of the file

My class which holds the constructor method of writing to a file
class Writer
{
public Writer(string filename, List<string> data)
{
FileStream ostrm;
StreamWriter writer;
TextWriter oldOut = Console.Out;
try
{
ostrm = new FileStream("C:/Users/kyle/Desktop/ConferenceSoftware/" + filename + ".txt", FileMode.OpenOrCreate, FileAccess.Write);
writer = new StreamWriter( ostrm );
}
catch (Exception e)
{
Console.WriteLine("Cannot open " + filename + ".txt for writing");
Console.WriteLine(e.Message);
return;
}
Console.SetOut(writer);
foreach (var _data in data)
{
Console.WriteLine( _data );
}
Console.SetOut(oldOut);
writer.Close();
ostrm.Close();
}
}
Inside my main method:
List<string> dataToAdd = new List<string>();
dataToAdd.Add("Example");
new Writer(Settings.ConferenceRoomName, dataToAdd);
However, if I already have text inside the file, instead appending to the file from the last line, it does it from the first line, ie:
Example // new added through method
Line that already exists // already in file
Line that already exists // already in file
// this is where I wanted it but it goes to the top
Any help would be appreciated, I don't see where I could target what line to start writing at.
Thanks in advance.
You need to use FileMode.Append instead of OpenOrCreate:
ostrm = new FileStream("C:/Users/kyle/Desktop/ConferenceSoftware/" +
filename + ".txt", FileMode.Append, FileAccess.Write);
See documentation (about FileMode.Append):
Opens the file if it exists and seeks to the end of the file, or creates a new file. This requires FileIOPermissionAccess.Append permission. FileMode.Append can be used only in conjunction with FileAccess.Write...
So it will also create the file if it does not exist.
If you don't want to create a non-existing file, you can check if it exists using File.Exists() before opening the stream.
When you create a new FileStream with FileMode.OpenOrCreate, it writes over the existing file. If you would like to append to the file, use FileMode.Append instead:
FileMode.Append: Opens the file if it exists and seeks to the end of the file, or creates a new file. This requires FileIOPermissionAccess.Append permission.
ostrm = new FileStream("C:/Users/kyle/Desktop/ConferenceSoftware/" + filename + ".txt", FileMode.Append, FileAccess.Write);
You want file mode Append instead of OpenOrCreate:
ostrm = new FileStream("C:/Users/kyle/Desktop/ConferenceSoftware/" + filename + ".txt", FileMode.Append, FileAccess.Write);
Both will create a new file if it doesn't exist, the difference is that OpenOrCreate starts writing at the beginning of the file and Append starts writing at the end of the file.
Reference: FileMode Enumeration

Streamwriter not throwing exception

In the following, streamwriter is not throwing an exception if the file does not exist.
I expected it to raise an exception, why doesn't it and how can I get it to do so?
var fileName = HttpContext.ApplicationInstance.Server.MapPath("~/App_Data/emails.txt");
FileStream fs = new FileStream(fileName, FileMode.Append);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(String.Format("{0}\t{1}", email, name));
sw.Flush();
sw.Close();
fs.Close();
Why?
FileStream fs = new FileStream(fileName, FileMode.Append);
This will create the file if it doesn't exist (and append to it if it does).
Assuming from your post (there is no question in it!) you don't want it to create a file first call File.Exists to ensure the file exists.
If you want to make sure you're appending to an existing file, use FileMode.Open and then Seek to the end before writing.
With File.Exists there is a (very slim) chance of an other process deleting the file after checking but before the construction of the FileStream.
Try this:
try
{
var fileName = HttpContext.ApplicationInstance.Server.MapPath("~/App_Data/emails.txt");
if (System.IO.File.Exists(fileName ))
{
FileStream fs = new FileStream(fileName, FileMode.Append);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(String.Format("{0}\t{1}", email, name));
sw.Flush();
sw.Close();
fs.Close();
}
else
{
//Throw error here
}
}
catch()
{
}

c# Replace openfileDialog to a none gui stream

I am trying to separate the MIME gui from the code i need. I am almost there just one more gui element i dont know how to replace. This element is the openfiledialog. Here a code snippet.
Program.cs
var sfd = new OpenFileDialog();
sfd.FileName = "C:\\eml\\" + validOutputFilename;
try
{
var writer = new MimeMessageWriter();
using (var fs = sfd.OpenFile()) writer.Write(message, fs);
}
catch (Exception ex)
{
//ignore
// need to log
}
message is an IMessage. A class created to store the information about an eml file. The open file dialog is allowing you to put in the file name with an eml extension and that is all. write.Write expects an IMessage and a stream. Inside writer.Write the file is being written The only part of the file that uses this code is when the file itself is writen at the end and write out any attachments. Here are those code snippets.
*MimeMessageWriter
-the attachment uses it here
var embeddedMessage = attachment.OpenAsMessage();
var messageWriter = new MimeMessageWriter();
var msgStream = new MemoryStream();
messageWriter.Write(embeddedMessage, msgStream);
var messageAttachment = ew DotNetOpenMail.FileAttachment(msgStream.ToArray());
messageAttachment.ContentType = "message/rfc822";
messageAttachment.FileName = filename + ".eml";
outMessage.AddMixedAttachment(messageAttachment);
-write out the file part of the file
using (var sw = new StreamWriter(stream))
sw.Write(outMessage.ToDataString());
I want to replace openFileDialog with something that will allow me to pass the filename to write out file in the MimeMessageWriter
Replace
using (var fs = sfd.OpenFile()) writer.Write(message, fs);
with
string fileName = #"c:\eml\myAttachment.eml";
using ( FileStream fs = new FileStream( fileName, FileMode.CreateNew ) )
{
writer.Write( message, fs )
}
See also: http://msdn.microsoft.com/de-de/library/47ek66wy.aspx

Edit RTF as plain text but unable to open it again

I have a RTF file that I want to open, replace a String "TEMPLATE_Name" and save. But after saving, the file cannot open correctly again. When I use MS Word, the file opens and shows the RTF raw code instead the text.
I am afraid I am breaking the format or the encoding but I don't really know how:
using (MemoryStream ms = new MemoryStream(1000))
using (StreamWriter sw = new StreamWriter(ms,Encoding.UTF8))
{
using (Stream fsSource = new FileStream(Server.MapPath("~/LetterTemplates/TestTemplate.rtf"), FileMode.Open))
using (StreamReader sr = new StreamReader(fsSource,Encoding.UTF8))
while (!sr.EndOfStream)
{
String line = sr.ReadLine();
line = line.Replace("TEMPLATE_Name", model.FirstName + " " + model.LastName);
sw.WriteLine(line);
}
ms.Position = 0;
using (FileStream fs = new FileStream(Server.MapPath("~/LetterTemplates/test.rtf"), FileMode.Create))
ms.CopyTo(fs);
}
Any idea about what could be the issue?
Thanks.
SOLUTION: One problem was what #BrokenGlass has pointed out, the fact I was not flushing the stream. The other was the encoding. In the fist line of the RTF file I can see:
{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\
So, even without understand anything about RTF, I set the encoding to code page 1252 and it works:
using (MemoryStream ms = new MemoryStream(1000))
using (StreamWriter sw = new StreamWriter(ms,Encoding.GetEncoding(1252)))
{
using (Stream fsSource = new FileStream(Server.MapPath("~/LetterTemplates/TestTemplate.rtf"), FileMode.Open))
using (StreamReader sr = new StreamReader(fsSource,Encoding.GetEncoding(1252)))
while (!sr.EndOfStream)
{
String line = sr.ReadLine();
line = line.Replace("TEMPLATE_Name", model.FirstName + " " + model.LastName);
sw.WriteLine(line);
}
sw.Flush();
ms.Position = 0;
using (FileStream fs = new FileStream(Server.MapPath("~/LetterTemplates/test.rtf"), FileMode.Create))
ms.CopyTo(fs);
}
StreamWriter is buffering content - make sure you call sw.Flush() before reading from your memory stream.
StreamWriter.Flush():
Clears all buffers for the current writer and causes any buffered data
to be written to the underlying stream.
Edit in light of comments:
A better alternative as #leppie alluded to is restructuring the code to use the using block to force flushing, instead of explicitly doing it:
using (MemoryStream ms = new MemoryStream(1000))
{
using (StreamWriter sw = new StreamWriter(ms,Encoding.UTF8))
{
//...
}
ms.Position = 0;
//Write to file
}
An even better alternative as #Slaks pointed out is writing to the file directly and not using a memory stream at all - unless there are other reasons you are doing this this seems to be the most straightforward solution, it would simplify your code and avoid buffering the file in memory.

Categories

Resources