オンザフライで圧縮する場合

タスクは簡単です。 いくつかのレポート、ファイルを作成し、ユーザーがASP.NETアプリケーションでそれらをダウンロードできるようにしたいとします。 アーカイブを使用すると便利なのはなぜですか?:a)ダウンロードボリュームが削減されますb)複数のファイルをバッチで提供できます。
.netには、 System.IO.CompressionにあるGZipを操作するための特別なクラスがあり、 GZipStreamと呼ばれますが、特定のような1つのアーカイブに複数のファイルを保存することはできません。 もちろん、本格的なzipアーカイブを作成するためにそれを使用する愛好家もいます(彼らはプログラムの助けを借りてのみ開くことができるように見えますが、少なくとも私はそのようなものだけに出会いました)。
.NET 3.0以降では、 System.IO.PackagingZipPackageクラスを使用できます。 このクラスは、WindowsBase.DLLアセンブリ(およそC:\ Program Files \ Reference Assemblies \ Microsoft \ Framework \ v3.0 \ WindowsBase.dllにあります)にあります。このアセンブリがGACにない理由はわかりませんが、すべてを使用する方法の例を次に示します。.NETでのZipアーカイブの作成(SharpZipLibのような外部ライブラリなし)
それでも、 SharpZipLibを使用する場合、メモリ内でアーカイブを行う方法は? 確かに、OutputZipStreamを介して実行できます。 しかし、ファイル名または完成したZipEntryを渡すことができるAdd()メソッド、およびIStaticDataSourceから継承された型を持つオブジェクトを渡す機能を持つFileZipクラスが好きでした。

そのため、FileZipクラスによるアーカイブのストリーム(ストリーム)として使用されるクラスを実装します。
/// <summary>
///
/// </summary>
class MemoryStreamStaticDataSource : ICSharpCode.SharpZipLib.Zip.IStaticDataSource, IDisposable
{
private MemoryStream MemoryStream { get ; set ; }

/// <summary>
/// MemoryStream
/// </summary>
/// <param name="bytes"></param>
public MemoryStreamStaticDataSource( byte [] bytes)
{
MemoryStream = new MemoryStream(bytes) { Position = 0 };
}

#region IStaticDataSource Members

public Stream GetSource()
{
return MemoryStream;
}

#endregion

#region IDisposable Members

public void Dispose()
{
if (MemoryStream != null )
MemoryStream.Dispose();
}

#endregion
}


* This source code was highlighted with Source Code Highlighter .

ファイルは、バイトのセット(バイト[])の形で既にありますが、アイデアはこれらのファイルを物理的に保存するのではなく、RAMのみに保存することです。 タスク-これらのファイルを自分で生成します。たとえば、次のコードを書きました。
/// <summary>
/// ,
/// </summary>
/// <returns></returns>
private static byte [] GetFirstFileData()
{
return GetFileData( @" ." );
}

/// <summary>
/// ,
/// </summary>
/// <returns></returns>
private static byte [] GetSecondFileData()
{
return GetFileData( @" ." );
}

private static byte [] GetFileData( string textdata)
{
return Encoding .UTF8.GetBytes(textdata);
}


* This source code was highlighted with Source Code Highlighter .

したがって、後者では、ZipFileクラスを使用して、偽のファイルをアーカイブに追加し、ページコンテンツの代わりにページをレスポンスに返します。
/// <summary>
/// , zip
/// </summary>
/// <param name="e"></param>
protected override void OnLoad( EventArgs e)
{
base .OnLoad(e);

Response.Clear();
// MIME
Response.ContentType = "application/zip" ;
//, file.zip
Response.AddHeader( "Content-Disposition" , string .Format( "attachment; filename=\"{0}\"" , HttpUtility.UrlEncodeUnicode( "file.zip" )));

// ( ) Response
byte [] bytes = GetZipData();
Response.OutputStream.Write(bytes, 0, bytes.Length);
}

private static byte [] GetZipData()
{
//
using (MemoryStream ms = new MemoryStream())
{
using (ICSharpCode.SharpZipLib.Zip.ZipFile file = new ICSharpCode.SharpZipLib.Zip.ZipFile(ms))
{
file.BeginUpdate();

//
file.Add( new MemoryStreamStaticDataSource(GetFirstFileData()), "file1.txt" );
//
file.Add( new MemoryStreamStaticDataSource(GetSecondFileData()), "file2.txt" );

file.CommitUpdate();
}

return ms.ToArray();
}
}


* This source code was highlighted with Source Code Highlighter .

その結果、2つのファイルを含むzipアーカイブを返すaspxページを取得します。
ダウンロード例...


Source: https://habr.com/ru/post/J56843/


All Articles