I'm using a MailMessage Queue and upon exiting the program I want to save the content of the queue.
I created a temp list and pass the contents of the queue to that. After that use a simple
StreamWriter to write each info out.
The only thing I can't seem to get is the path of the attachment. As far as I know I can't just simply save out the mailmessages so I thought this will work just as well, but if there is simpler/different solution that's great.
List<MailMessage> temp = queue.ToList<MailMessage>();
Stream stream = File.Open("Queue" +".osl", FileMode.Create);
StreamWriter s = new StreamWriter(stream);
foreach (MailMessage x in temp)
{
s.WriteLine(x.From.Address + x.To[0].Address + x.Body + x.Subject + x.Attachments[0].Name);
}
s.Close();
stream.Close();
I know it is an old question, but there is no answer here, and this really works:
(attachmentObject.ContentStream as System.IO.FileStream).Name
In your specific case it would be:
s.WriteLine(x.From.Address + x.To[0].Address + x.Body + x.Subject + (x.Attachments[0].ContentStream as System.IO.FileStream).Name);
Hope it helps somebody!
You can also use:
Path.GetFullPath(x.Attachments[0].Name);
Related
Here, I create 2 new files, and when I try to File.WriteAllLines(), it returns an IOException saying that the file is already being used by another process:
Directory.CreateDirectory(tempShiftPath);
File.Create(tempShiftPath + "Info.shift");
File.Create(tempShiftPath + "Legs.shift");
string[] infoContents =
{
Convert.ToString(shift.TimeFrame.Start) + ";" + Convert.ToString(shift.TimeFrame.End),
shift.Description
};
File.WriteAllLines(tempShiftPath + "Info.shift", infoContents); // Error occures here
return shift;
Things I have tried
I have already read through this question, and I am sure that the "other process" is my process.
I have also added a few seconds of sleep between the creat and the write methods, but that obviously didn't work.
Honestly, I have no idea what is wrong, because it worked some time ago, but now it doesn't.
File.Create opens a stream to the file. This stream needs to closed, or you will get the error you describe.
However, File.WriteAllLines creates the file on its own, so there is no need for the File.Create statement.
This should work just fine:
Directory.CreateDirectory(tempShiftPath);
string[] infoContents =
{
Convert.ToString(shift.TimeFrame.Start) + ";" + Convert.ToString(shift.TimeFrame.End),
shift.Description
};
File.WriteAllLines(tempShiftPath + "Info.shift", infoContents); // No error occurs here
return shift;
File.Create is meant to be used something like this:
using (FileStream fs = File.Create(path))
{
fs.Write(byteArray, 0, length);
}
I'm using c#. I'm receiving an error about a path is currently accessed by other processes. What my system is trying to do is to access the path: #"C:\temps\" + client_ids + "_" + rown + ".pdf" and use the same path for attachment before sending it to client's email.
here's what I've done so far. I comment out some of my code because I'm not sure what to do.
FileStream fs = null;
using (fs = new FileStream(#"C:\\temps\\" + client_ids + "_" +
rown + ".pdf",
FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
{
TextReader tr = new StreamReader(fs);
//report.ExportToDisk
//(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat,tr);
//report.Dispose();
//Attachment files = new Attachment(tr);
//Mailmsg.Attachments.Add(files);
//Clients.Send(Mailmsg);
}
you can make temp copy of file before you use it in mail attachment and then use the copy instead of the original file
You cannot attach a file to an email if that file is open. You must close (save) the file first.
While #ali answer is technically correct, it is unnecessary. Why go through the overhead of creating a copy of the file which then needs to be deleted, etc.?
Assuming I understand what you are trying to do correctly, simply move your code for mail to after the file is successfully created and saved. And, I don't think you need the overhead of either the filestream or the textreader. As long as your report object can save the file to disk someplace, you can attach that file to your email message and then send it.
While I do not claim to know anything about how Crystal Decisions handles exports, etc. Perhaps something like this would work:
(I got this code from: https://msdn.microsoft.com/en-us/library/ms226036(v=vs.90).aspx)
private void ExportToDisk (string fileName)
{
ExportOptions exportOpts = new ExportOptions();
DiskFileDestinationOptions diskOpts =
ExportOptions.CreateDiskFileDestinationOptions();
exportOpts.ExportFormatType = ExportFormatType.RichText;
exportOpts.ExportDestinationType =
ExportDestinationType.DiskFile;
diskOpts.DiskFileName = fileName;
exportOpts.ExportDestinationOptions = diskOpts;
Report.Export(exportOpts);
}
You will need to change the ExportFormatType property.
Then, simply attach the file to your email and send:
Attachment Files = new Attachment(filename);
Mailmsg.Attachments.add(files);
Clients.Send(Mailmsg);
I'm trying to detect if a file exists at runtime, if not, create it. However I'm getting this error when I try to write to it:
The process cannot access the file 'myfile.ext' because it is being used by another process.
string filePath = string.Format(#"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre);
if (!File.Exists(filePath))
{
File.Create(filePath);
}
using (StreamWriter sw = File.AppendText(filePath))
{
//write my text
}
Any ideas on how to fix it?
File.Create(FilePath).Close();
File.WriteAllText(FileText);
I want to update this answer to say that this is not really the most efficient way to write all text. You should only use this code if you need something quick and dirty.
I was a young programmer when I answered this question, and back then I thought I was some kind of genius for coming up with this answer.
The File.Create method creates the file and opens a FileStream on the file. So your file is already open. You don't really need the file.Create method at all:
string filePath = #"c:\somefilename.txt";
using (StreamWriter sw = new StreamWriter(filePath, true))
{
//write to the file
}
The boolean in the StreamWriter constructor will cause the contents to be appended if the file exists.
When creating a text file you can use the following code:
System.IO.File.WriteAllText("c:\test.txt", "all of your content here");
Using the code from your comment. The file(stream) you created must be closed. File.Create return the filestream to the just created file.:
string filePath = "filepath here";
if (!System.IO.File.Exists(filePath))
{
System.IO.FileStream f = System.IO.File.Create(filePath);
f.Close();
}
using (System.IO.StreamWriter sw = System.IO.File.AppendText(filePath))
{
//write my text
}
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();
File.Create returns a FileStream. You need to close that when you have written to the file:
using (FileStream fs = File.Create(path, 1024))
{
Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
You can use using for automatically closing the file.
I updated your question with the code snippet. After proper indenting, it is immediately clear what the problem is: you use File.Create() but don't close the FileStream that it returns.
Doing it that way is unnecessary, StreamWriter already allows appending to an existing file and creating a new file if it doesn't yet exist. Like this:
string filePath = string.Format(#"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre);
using (StreamWriter sw = new StreamWriter(filePath, true)) {
//write my text
}
Which uses this StreamWriter constructor.
I know this is an old question, but I just want to throw this out there that you can still use File.Create("filename")", just add .Dispose() to it.
File.Create("filename").Dispose();
This way it creates and closes the file for the next process to use it.
This question has already been answered, but here is a real world solution that
checks if the directory exists and adds a number to the end if the text file
exists. I use this for creating daily log files on a Windows service I wrote. I
hope this helps someone.
// How to create a log file with a sortable date and add numbering to it if it already exists.
public void CreateLogFile()
{
// filePath usually comes from the App.config file. I've written the value explicitly here for demo purposes.
var filePath = "C:\\Logs";
// Append a backslash if one is not present at the end of the file path.
if (!filePath.EndsWith("\\"))
{
filePath += "\\";
}
// Create the path if it doesn't exist.
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
// Create the file name with a calendar sortable date on the end.
var now = DateTime.Now;
filePath += string.Format("Daily Log [{0}-{1}-{2}].txt", now.Year, now.Month, now.Day);
// Check if the file that is about to be created already exists. If so, append a number to the end.
if (File.Exists(filePath))
{
var counter = 1;
filePath = filePath.Replace(".txt", " (" + counter + ").txt");
while (File.Exists(filePath))
{
filePath = filePath.Replace("(" + counter + ").txt", "(" + (counter + 1) + ").txt");
counter++;
}
}
// Note that after the file is created, the file stream is still open. It needs to be closed
// once it is created if other methods need to access it.
using (var file = File.Create(filePath))
{
file.Close();
}
}
I think I know the reason for this exception. You might be running this code snippet in multiple threads.
you can just use using keyword around File.Create(path) to finalize the process
using(File.Create(path));
Try this: It works in any case, if the file doesn't exists, it will create it and then write to it. And if already exists, no problem it will open and write to it :
using (FileStream fs= new FileStream(#"File.txt",FileMode.Create,FileAccess.ReadWrite))
{
fs.close();
}
using (StreamWriter sw = new StreamWriter(#"File.txt"))
{
sw.WriteLine("bla bla bla");
sw.Close();
}
I want to append lines to my file. I am using code:
StreamWriter sw = new StreamWriter("gamedata.txt", true);
sw.Write(the_final);
sw.Dispose();
at the moment it's outputting everything in a row.
Use sw.WriteLine(the_final); or sw.Write(the_final + "\n");
But much cleaner:
System.IO.File.AppendAllText("gamedata.txt", the_final + Environment.NewLine);
You should use writeline for writing in a new line sw.WriteLine(the_final)
It Writes a line terminator to the text stream
http://msdn.microsoft.com/en-us/library/ebb1kw70.aspx
You can use the WriteLine() method instead of Write().
I think the issue is when you're constructing your output into the variable: the_final
You need to insert new lines. You can do this by something along these lines:
the_final = "My First Line" + "\r\n";
the_final += "My Second Line!" + "\r\n";
thirdline = "My Third Line!";
the_final += thirdline + "\r\n";
The "\r\n" will produce the carriage return you're looking for.
The other suggestions everyone is making will only append 1 new line to the end of your output, leaving the rest on a single line still.
sw.Writeline(); writes a new line at the end.
sw.Write(); does not append a new line at the end.
Use sw.WriteLine() over Write()
MSDN:
Writes a line terminator to the text stream.
http://msdn.microsoft.com/en-us/library/system.io.streamwriter.writeline.aspx
Add a newline character manually
StreamWriter sw = new StreamWriter("gamedata.txt", true);
sw.Write(the_final + "\n");
sw.Dispose();
or use the writeline method
This question is easily answered by a short google search.It's good form to do a bit of research prior to posting
While everyone else has pretty much answered your initial question, may I also suggest this improvement?
using(StreamWriter sw = new StreamWriter("gamedata.txt", true))
{
sw.WriteLine(the_final);
}
When you have an object that inherits from IDisposable, it's good form to use using instead of disposing it manually. For one thing, using will dispose your object even if an exception is encountered.
Using documentation
I'm trying to detect if a file exists at runtime, if not, create it. However I'm getting this error when I try to write to it:
The process cannot access the file 'myfile.ext' because it is being used by another process.
string filePath = string.Format(#"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre);
if (!File.Exists(filePath))
{
File.Create(filePath);
}
using (StreamWriter sw = File.AppendText(filePath))
{
//write my text
}
Any ideas on how to fix it?
File.Create(FilePath).Close();
File.WriteAllText(FileText);
I want to update this answer to say that this is not really the most efficient way to write all text. You should only use this code if you need something quick and dirty.
I was a young programmer when I answered this question, and back then I thought I was some kind of genius for coming up with this answer.
The File.Create method creates the file and opens a FileStream on the file. So your file is already open. You don't really need the file.Create method at all:
string filePath = #"c:\somefilename.txt";
using (StreamWriter sw = new StreamWriter(filePath, true))
{
//write to the file
}
The boolean in the StreamWriter constructor will cause the contents to be appended if the file exists.
When creating a text file you can use the following code:
System.IO.File.WriteAllText("c:\test.txt", "all of your content here");
Using the code from your comment. The file(stream) you created must be closed. File.Create return the filestream to the just created file.:
string filePath = "filepath here";
if (!System.IO.File.Exists(filePath))
{
System.IO.FileStream f = System.IO.File.Create(filePath);
f.Close();
}
using (System.IO.StreamWriter sw = System.IO.File.AppendText(filePath))
{
//write my text
}
FileStream fs= File.Create(ConfigurationManager.AppSettings["file"]);
fs.Close();
File.Create returns a FileStream. You need to close that when you have written to the file:
using (FileStream fs = File.Create(path, 1024))
{
Byte[] info = new UTF8Encoding(true).GetBytes("This is some text in the file.");
// Add some information to the file.
fs.Write(info, 0, info.Length);
}
You can use using for automatically closing the file.
I updated your question with the code snippet. After proper indenting, it is immediately clear what the problem is: you use File.Create() but don't close the FileStream that it returns.
Doing it that way is unnecessary, StreamWriter already allows appending to an existing file and creating a new file if it doesn't yet exist. Like this:
string filePath = string.Format(#"{0}\M{1}.dat", ConfigurationManager.AppSettings["DirectoryPath"], costCentre);
using (StreamWriter sw = new StreamWriter(filePath, true)) {
//write my text
}
Which uses this StreamWriter constructor.
I know this is an old question, but I just want to throw this out there that you can still use File.Create("filename")", just add .Dispose() to it.
File.Create("filename").Dispose();
This way it creates and closes the file for the next process to use it.
This question has already been answered, but here is a real world solution that
checks if the directory exists and adds a number to the end if the text file
exists. I use this for creating daily log files on a Windows service I wrote. I
hope this helps someone.
// How to create a log file with a sortable date and add numbering to it if it already exists.
public void CreateLogFile()
{
// filePath usually comes from the App.config file. I've written the value explicitly here for demo purposes.
var filePath = "C:\\Logs";
// Append a backslash if one is not present at the end of the file path.
if (!filePath.EndsWith("\\"))
{
filePath += "\\";
}
// Create the path if it doesn't exist.
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
// Create the file name with a calendar sortable date on the end.
var now = DateTime.Now;
filePath += string.Format("Daily Log [{0}-{1}-{2}].txt", now.Year, now.Month, now.Day);
// Check if the file that is about to be created already exists. If so, append a number to the end.
if (File.Exists(filePath))
{
var counter = 1;
filePath = filePath.Replace(".txt", " (" + counter + ").txt");
while (File.Exists(filePath))
{
filePath = filePath.Replace("(" + counter + ").txt", "(" + (counter + 1) + ").txt");
counter++;
}
}
// Note that after the file is created, the file stream is still open. It needs to be closed
// once it is created if other methods need to access it.
using (var file = File.Create(filePath))
{
file.Close();
}
}
I think I know the reason for this exception. You might be running this code snippet in multiple threads.
you can just use using keyword around File.Create(path) to finalize the process
using(File.Create(path));
Try this: It works in any case, if the file doesn't exists, it will create it and then write to it. And if already exists, no problem it will open and write to it :
using (FileStream fs= new FileStream(#"File.txt",FileMode.Create,FileAccess.ReadWrite))
{
fs.close();
}
using (StreamWriter sw = new StreamWriter(#"File.txt"))
{
sw.WriteLine("bla bla bla");
sw.Close();
}