📜 ⬆️ ⬇️

When you need to zip on the fly

The task is trivial. You make some reports, files and want to enable the user to download them in their ASP.NET application. Why is it useful to use archiving ?: a) the downloadable volume decreases b) you can give files in batches of several.
In .net there is a special class for working with GZip, located in System.IO.Compression , and called GZipStream , but it does not allow storing several files in one archive, such specificity. There are, of course, enthusiasts who, with the help of it, create full-fledged zip archives (although they can, it seems, open them only with the help of their programs — at least, I came across only those).
In .NET 3.0 and higher, you can use the ZipPackage class from System.IO.Packaging , which is located in the WindowsBase.DLL assembly (located approximately in C: \ Program Files \ Reference Assemblies \ Microsoft \ Framework \ v3.0 \ WindowsBase.dll), I do not know why this assembly is not in the GAC, here is an example of how to use all this: Creating Zip archives in .NET (without an external library like SharpZipLib) .
But still if you use SharpZipLib , how to make archiving in memory? Surely, you can do it through OutputZipStream. But I liked the FileZip class, which has an Add () method to which you can transfer the file name, or a ready-made ZipEntry, as well as the ability to transfer an object with a type inherited from the IStaticDataSource.

So, let's implement a class that will be used as a Stream (stream) for archiving by the FileZip class:
/// <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 .

Let us have files, we will already have in the form of a set of bytes (byte []), the idea is that we do not want to store these files physically, only in RAM. Task - we generate these files ourselves, for example, I wrote the following code:
/// <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 .

So, the latter, using the ZipFile class, add our sham files to the archive and return pages to the Response (instead of the page content).
/// <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 .

As a result, we will have an aspx page that will return a zip archive with two files.
Download an example ...

')

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


All Articles