使用 Using 无法读取流

Stream was not readable with Using

我遇到错误

File is being used by another process

正在尝试为 FileStream 实施 using。但是,我遇到了Stream was not readable的错误。

这是我的代码:

之前:工作正常,但定期遇到 'file being used by another process' 错误

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

之后:遇到'stream was not readable'错误

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

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

这意味着它所说的:一些其他进程正在接触该文件。如果你想解决这个问题,你需要弄清楚是什么在使用这个文件。无论您是否使用 using 都会发生这种情况。

如果此代码运行 并行多次,可能是您自己的代码干扰了。无论哪种方式,您都可以通过只读方式打开它来避免它,但特别允许其他进程打开它进行写操作。你会这样做:

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

encounter 'stream was not readable' error

这取决于 AddFileAttachment 的实现方式。您没有显示堆栈跟踪,因此它可能不会读取流,直到您调用 SendAndSaveCopy(),它在 using 之外并且流已关闭。

解决这个问题的一个简单方法是只使用 the overload of AddFileAttachment that just takes the path to the file as a string,这样您就不需要自己管理 FileStream

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

我使用 Path.Combine 因为它避免了在您的 EmailSaveFilePath 设置中可能有或没有尾随 \ 的问题。

我想知道你是否可以不保存文件而只使用 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();