无法写入新的 MemoryStream - 流已关闭
Cannot write to new MemoryStream - Stream closed
我有一些方法可以将一个或多个文件压缩为 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 对象的输出参数,即使在尝试使用内存流的多个新实例后,我仍然收到相同的错误。
其中一种方法如下:
/// <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 框架。
正如我所怀疑的,代码拥有您作为文件传递的 Stream
的所有权,因此您不能 Close()/Dispose()
它...
写成:
var _memStream = new MemoryStream(file.Contents);
zipArchive.AddEntry(file.Filename, _memStream, true);
应该使用this overload。 true
是为了在不使用时关闭 Stream
。
可能它会自动发现 length
(我看到它是一个可选值,默认为 0
)
我有一些方法可以将一个或多个文件压缩为 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 对象的输出参数,即使在尝试使用内存流的多个新实例后,我仍然收到相同的错误。
其中一种方法如下:
/// <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 框架。
正如我所怀疑的,代码拥有您作为文件传递的 Stream
的所有权,因此您不能 Close()/Dispose()
它...
写成:
var _memStream = new MemoryStream(file.Contents);
zipArchive.AddEntry(file.Filename, _memStream, true);
应该使用this overload。 true
是为了在不使用时关闭 Stream
。
可能它会自动发现 length
(我看到它是一个可选值,默认为 0
)