216

MemoryStream次のように使用して、単純なデモ テキスト ファイルで ZIP アーカイブを作成しようとしています。

using (var memoryStream = new MemoryStream())
using (var archive = new ZipArchive(memoryStream , ZipArchiveMode.Create))
{
    var demoFile = archive.CreateEntry("foo.txt");

    using (var entryStream = demoFile.Open())
    using (var streamWriter = new StreamWriter(entryStream))
    {
        streamWriter.Write("Bar!");
    }

    using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
    {
        stream.CopyTo(fileStream);
    }
}

このコードを実行すると、アーカイブ ファイル自体は作成されますが、foo.txtは作成されません。

ただし、MemoryStream直接ファイル ストリームに置き換えると、アーカイブは正しく作成されます。

using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
using (var archive = new ZipArchive(fileStream, FileMode.Create))
{
    // ...
}

MemoryStreamを使用せずに ZIP アーカイブを作成することは可能FileStreamですか?

4

12 に答える 12

6

メモリ ストリームの書き込みを終了してから、バッファを読み戻す必要があります。

        using (var memoryStream = new MemoryStream())
        {
            using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create))
            {
                var demoFile = archive.CreateEntry("foo.txt");

                using (var entryStream = demoFile.Open())
                using (var streamWriter = new StreamWriter(entryStream))
                {
                    streamWriter.Write("Bar!");
                }
            }

            using (var fileStream = new FileStream(@"C:\Temp\test.zip", FileMode.Create))
            {
                var bytes = memoryStream.GetBuffer();
                fileStream.Write(bytes,0,bytes.Length );
            }
        }
于 2013-06-21T17:37:54.353 に答える
2

私はパーティーに遅れましたが、パラメーターZipArchiveを設定するために のコンストラクターにアクセスできずleaveOpen、ZIP をディスクに書き込みたくないシナリオがあります。私の場合、AsiceArchive内部で使用しているクラスは を作成しますZipArchiveが、true に設定されませんleaveOpen

Streamすべての呼び出しを内部ストリームに委譲するサブクラスを作成しました(ReSharper で数回クリックするだけです)。このクラスは使い捨てではないため、ZipArchiveが破棄されても、内部ストリームには何も起こりません。

public class NondisposingStreamWrapper : Stream
{
    private readonly Stream _streamImplementation;

    public NondisposingStreamWrapper(Stream inner) => _streamImplementation = inner;

    public override void Flush() => _streamImplementation.Flush();

    public override int Read(byte[] buffer, int offset, int count) => _streamImplementation.Read(buffer, offset, count);

    public override long Seek(long offset, SeekOrigin origin) => _streamImplementation.Seek(offset, origin);

    public override void SetLength(long value) => _streamImplementation.SetLength(value);

    public override void Write(byte[] buffer, int offset, int count) => _streamImplementation.Write(buffer, offset, count);

    public override bool CanRead => _streamImplementation.CanRead;

    public override bool CanSeek => _streamImplementation.CanSeek;

    public override bool CanWrite => _streamImplementation.CanWrite;

    public override long Length => _streamImplementation.Length;

    public override long Position
    {
        get => _streamImplementation.Position;
        set => _streamImplementation.Position = value;
    }
}

次のように使用します。

using var memoryStream = new MemoryStream();
var output = new NondisposingStreamWrapper(memoryStream);

using (var archive = new ZipArchive(output, ZipArchiveMode.Create))
{
    // add entries to archive
}

memoryStream.Flush();
memoryStream.Position = 0;

// write to file just for testing purposes
File.WriteAllBytes("out.zip", memoryStream.ToArray());
于 2021-06-22T21:43:36.593 に答える
1

これは、エンティティを XML ファイルに変換してから圧縮する方法です。

private  void downloadFile(EntityXML xml) {

string nameDownloadXml = "File_1.xml";
string nameDownloadZip = "File_1.zip";

var serializer = new XmlSerializer(typeof(EntityXML));

Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("content-disposition", "attachment;filename=" + nameDownloadZip);

using (var memoryStream = new MemoryStream())
{
    using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
    {
        var demoFile = archive.CreateEntry(nameDownloadXml);
        using (var entryStream = demoFile.Open())
        using (StreamWriter writer = new StreamWriter(entryStream, System.Text.Encoding.UTF8))
        {
            serializer.Serialize(writer, xml);
        }
    }

    using (var fileStream = Response.OutputStream)
    {
        memoryStream.Seek(0, SeekOrigin.Begin);
        memoryStream.CopyTo(fileStream);
    }
}

Response.End();

}

于 2016-08-25T22:09:55.153 に答える