gymcode
gymcode

Reputation: 4623

Stream was not readable with Using

I am getting an error

File is being used by another process

trying to implement using for a FileStream. However, I encountered the error of Stream was not readable.

This is my code:

Before: working, but encounters 'file being used by another process' error periodically

EmailMessage responseMessageWithAttachment = responseMessage.Save();

foreach (var attachment in email.Attachments)
{
    if (attachment is FileAttachment)
    {
        FileAttachment fileAttachment = attachment as FileAttachment;
        fileAttachment.Load();
        fileAttachment.Load(AppConfig.EmailSaveFilePath + fileAttachment.Name);

        FileStream fs = new FileStream(AppConfig.EmailSaveFilePath + fileAttachment.Name, FileMode.OpenOrCreate);
        responseMessageWithAttachment.Attachments.AddFileAttachment(attachment.Name, fs);
    }
}
responseMessageWithAttachment.SendAndSaveCopy();

After: encounters 'stream was not readable' error

EmailMessage responseMessageWithAttachment = responseMessage.Save();

foreach (var attachment in email.Attachments)
{
    if (attachment is FileAttachment)
    {
        FileAttachment fileAttachment = attachment as FileAttachment;
        fileAttachment.Load();
        fileAttachment.Load(AppConfig.EmailSaveFilePath + fileAttachment.Name);

        using (FileStream fs = new FileStream(AppConfig.EmailSaveFilePath + fileAttachment.Name, FileMode.OpenOrCreate))
        {
            responseMessageWithAttachment.Attachments.AddFileAttachment(attachment.Name, fs);
        };
    }
}
responseMessageWithAttachment.SendAndSaveCopy();

Upvotes: 1

Views: 1505

Answers (2)

tmaj
tmaj

Reputation: 34947

I wonder if you can avoid saving the files and just use Content and AddFileAttachment(String, Byte[])

foreach (var attachment in email.Attachments)
{
    if (attachment is FileAttachment)
    {
        FileAttachment fileAttachment = attachment as FileAttachment;
        fileAttachment.Load();
        responseMessageWithAttachment.Attachments.AddFileAttachment(attachment.Name, fileAttachment.Content);
    }
}
responseMessageWithAttachment.SendAndSaveCopy();

Upvotes: 1

Gabriel Luci
Gabriel Luci

Reputation: 40858

working, but encounter 'file being used by another process' error periodically

This means what it says: some other process is touching the file. If you want to solve this, you need to figure out what's using the file. This will happen whether you use using or not.

If this code is running multiple times in parallel, it could be your own code interfering. Either way, you could avoid it by open for reading only, but specifically allowing other processes to open it for writing. You would do that like this:

var fs = new FileStream(Path.Combine(AppConfig.EmailSaveFilePath, fileAttachment.Name),
                        FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

encounter 'stream was not readable' error

This depends on how AddFileAttachment is implemented. You don't show the stack trace, so it's possible that it doesn't read the stream until you call SendAndSaveCopy(), which is outside the using and the stream is closed.

An easy way to work around this is to just use the overload of AddFileAttachment that just takes the path to the file as a string, so you don't need to manage the FileStream yourself:

responseMessageWithAttachment.Attachments.AddFileAttachment(attachment.Name,
               Path.Combine(AppConfig.EmailSaveFilePath, fileAttachment.Name));

I use Path.Combine since it avoids problems where there may or may not be a trailing \ in your EmailSaveFilePath setting.

Upvotes: 1

Related Questions