使用System.IO.Compression.ZipArchive时避免MemoryStream.ToArray() - c#

将字符串转换为压缩文本文件的辅助方法:

public static System.Net.Mail.Attachment CreateZipAttachmentFromString(string content, string filename)
{
  using (MemoryStream memoryStream = new MemoryStream())
  {
    using (ZipArchive zipArchive = new ZipArchive(memoryStream, ZipArchiveMode.Update))
    {
      ZipArchiveEntry zipArchiveEntry = zipArchive.CreateEntry(filename);
      using (StreamWriter streamWriter = new StreamWriter(zipArchiveEntry.Open()))
      {
        streamWriter.Write(content);
      }

    }

    MemoryStream memoryStream2 = new MemoryStream(memoryStream.ToArray(), false);

    return new Attachment(memoryStream2, filename + ".zip", MediaTypeNames.Application.Zip);
  }
}

我真的希望避免将第一个内存流转换为数组,在其上制作另一个内存流以读取它,并将其传递给附件。我的逻辑是,为什么将X兆字节复制到内存中的另一个位置以建立另一个指向该副本的流,而这实际上正是我们刚开始使用的内容。这相当于冗余的多兆字节,例如if(myBool == true)

因此,我想起了我想回到第一个内存流的开始,然后附件可以读取的内容。或者我将建立另一个指向第一个内存流的内存流,并设置了offset和length参数,因此会读什么

这两种方法都不可行,因为ZipArchive似乎仅在控制脱离了using块并处理了ziparchive时才将数据推入内存流(在我的情况下)。处置它还处置MemoryStream,几乎所有东西(除ToArray()和GetBuffer()之外)都抛出ObjectDisposedException。

最终,在ZipArchive将数据泵入数据并将其泵入之前,我无法找到它或获取其长度,偏移量通常为零,长度绝对为零,因此这些值无用

有没有一种好的最佳方法,而无需配置我自己的超大缓冲区(然后使它无法由MemoryStream扩展),从而避免用这种方法将文件大小的内存字节消耗掉大约2倍?

参考方案

.NET中大多数设计良好的流和流用户都有一个附加的布尔参数,可用于指示它们在处置时将“基本流”(可怕的名称)保持打开状态。

这是ZipArchive的constructor:

public ZipArchive(
    Stream stream,
    ZipArchiveMode mode,
    bool leaveOpen
)

是否有System.IO.Stream的接口? - c#

我正在编写一个需要接收一个对象,记录其当前状态,更新该对象并将其传递给另一个类的类。唯一的问题是,您只能从一个类继承,而我需要在我的项目中继承一个类。我对System.IO.Stream感兴趣,因为如果需要,我可以将此类移动到它自己的线程中,而无需大多数(如果不是全部)套接字和IPC的其他方法。主要问题是System.IO.Stream是否有接口?如果没有,…

使用System.Drawing.Font限制字体大小? - c#

我正在使用内置的“字体”对话框来选择字体大小和样式。字体大小范围是从8到72。我需要限制用户不要选择超过20的大小。是否可以将字体大小从22禁用或完全不显示22?我没有在Font类上看到任何属性来执行此操作?感谢您的任何建议。 c#参考方案 我没有在Font类上看到任何属性来执行此操作?这是因为它是FontDialog类的属性,而不是Font类的属性。例如:…

使用System.loadLibrary加载Python C扩展DLL - java

我有一个扩展名为Python C Extension DLL的pyd,我想通过Windows上的System.loadLibrary 在Java中加载。似乎没有办法加载扩展名不同于* .dll的dll。有没有建议的方法来解决这个问题?用例我打算将Python嵌入Java。我创建了一个要在JAVA中加载的扩展dll,使用JNI与该扩展dll进行通信,该扩展dl…

在不使用java.io. *的情况下获取FileChannel(使用纯NIO) - java

最近,我对此answer进行了评论,如果我想使用“纯NIO”,则应该远离java.io。这是简化的代码(复制文件):private static void copy(File source, File destination) throws IOException { long length = source.length(); FileChannel in…

C#:使用System.Reflection.GetFields()显示字段元数据 - c#

This question already has answers here: Closed 8 years ago. Possible Duplicate: Find a private field with Reflection?我正在尝试使用System.Reflection.GetFields()方法显示类的字段名称。问题是,仅当字段被声明为“ pu…