无法写入新的MemoryStream - Stream已关闭

时间:2017-03-17 13:21:57

标签: c# stream memorystream

我有将一个或多个文件压缩为tar(.gz)或zip的方法。 在这些文件中,我使用已经加载到内存中的字节,我只需要将它们压缩,然后将压缩文件写入MemoryStream。

起初,我正在使用内存流引用来节省资源。 我开始从应用程序收到以下消息:

[MailArchive] [14:06] [Fatal] A fatal error occurred while executing the command "export-email" in the plugin RestService!
[MailArchive] [14:06] [Fatal] This error was not caught by the command handler and may have caused a severe application crash!
[MailArchive] [14:06] [Fatal] Error details are following:
[MailArchive] [14:06] [Trace] Cannot access a closed Stream.
[MailArchive] [14:06] [Trace] mscorlib
[MailArchive] [14:06] [Trace]    at System.IO.__Error.StreamIsClosed()
   at System.IO.MemoryStream.Seek(Int64 offset, SeekOrigin loc)
   at SharpCompress.Archives.AbstractWritableArchive`2.<>c.<SaveTo>b__18_0(IWritableArchiveEntry x)
   at SharpCompress.Utility.ForEach[T](IEnumerable`1 items, Action`1 action)
   at SharpCompress.Archives.AbstractWritableArchive`2.SaveTo(Stream stream, WriterOptions options)
   at SharpCompress.Archives.Zip.ZipArchive.SaveTo(Stream stream)
   at De.Nwt.MailArchive.MailProcessor_2.MailProcessor_2.CompressToZip(MemoryStream& memStream, IntFile[] files) in C:\Users\sc\Documents\Git\MailArchive\MailProcessor_2\Src\Classes\MailProcessor_2.FileIO.cs:line 312
   at De.Nwt.MailArchive.MailProcessor_2.MailProcessor_2.ExportAttachments(ArchiveType archType, String domain, String messageId, Boolean singleAttachment, String fName, Int32 idx) in C:\Users\sc\Documents\Git\MailArchive\MailProcessor_2\Src\Classes\MailProcessor_2.CommandHandling.cs:line 360
   at De.Nwt.MailArchive.MailProcessor_2.MailProcessor_2.Command_ExportEmail(Command sender, String[] args) in C:\Users\sc\Documents\Git\MailArchive\MailProcessor_2\Src\Classes\MailProcessor_2.CommandHandling.cs:line 192
   at De.Nwt.MailArchive.Commands.Command.Invoke(String[] args) in C:\Users\sc\Documents\Git\MailArchive\Command\Src\Classes\Command.cs:line 120
   at De.Nwt.MailArchive.MainClass.baseEvents_PluginExecutedCommand(Object sender, PluginExecutedCommandEventArgs e) in C:\Users\sc\Documents\Git\MailArchive\MailArchive\Src\Classes\MailArchive.cs:line 979
[MailArchive] [14:06] [Warn] Will return a CommandExceptionResult containing the above error!

收到这些错误后,我转而使用了MemoryStream对象的out-parameters,即使尝试使用多个新的内存流实例,我仍然会收到相同的错误。

其中一种方法如下:

    /// <summary>
    /// Compresses one or more files to a zip archive.
    /// </summary>
    /// <param name="memStream">The memory stream.</param>
    /// <param name="files">The files.</param>
    void CompressToZip(out MemoryStream memStream, params MailProcessor_2.IntFile[] files) {
        using (var zipArchive = ZipArchive.Create()) {
            foreach (var file in files) {
                using (var _memStream = new MemoryStream(file.Contents)) {
                    zipArchive.AddEntry(file.Filename, _memStream, _memStream.Length);
                }
            }

            var tmpStream = new MemoryStream();
            zipArchive.SaveTo(tmpStream); // The error occurrs here
            memStream = tmpStream;
        }
    }

我已经完成了调试器,并在发生错误的地方设置断点,tmpStream的_isOpen变量设置为true。

非常感谢任何有关此事的帮助。

编辑:我忘了提到我正在使用SharpCompress进行Tar-archival和Zip压缩。对于Gzip压缩,我使用标准的.Net框架。

1 个答案:

答案 0 :(得分:3)

我怀疑,代码会将您传递的Stream作为文件的所有权,因此您无法Close()/Dispose()它...

将其写为:

var _memStream = new MemoryStream(file.Contents);
zipArchive.AddEntry(file.Filename, _memStream, true);

应使用this overloadtrue以便在未使用时关闭Stream

可能它会自动发现length(我发现它是一个可选值,默认为0