Search code examples
c#filestream

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

Solution

  • 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.