Asp.Net实现在线网站安装(中)——压缩与解压
作者:翅膀的初衷 来源:本站原创 发布时间:2014-07-18 查看数:54741
上一篇我们介绍了网站在线安装的下载功能,压缩包下载后,就可以进行解压了,但是考虑到安装文件的精减问题,在这里我使用了Gizp算法。
本文介绍如何使用Gzip进行文件的压缩与解压。
在之前,我们来讲下规则与原理。我们将所有的文件与文件夹信息,统一放到一个字典对象中,以文件路径做为字典的Key,为了方便区分文件与文件夹,在路径的第一个字符用来标识类型,文件夹为0,文件为1。
因为压缩功能只是方便我们自己打包发布版本,不需要用户下载使用,所以我们需要新开一个页面(也可以建一个windows程序,用来以后统一打包发布)
在这里,我们新建一个aspx页,命名为FilesCreateZip.aspx,代码如下:
<%@ Page Language="C#" AutoEventWireup="true" %>
protected void Page_Load(object sender, EventArgs e)
{
CreateSetupZip(Server.MapPath("~/"), Server.MapPath("~/setup.zip"));
Response.Write("success");
}
public void CreateSetupZip(string basePath, string savePath)
{
System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(basePath);
System.Collections.Generic.Dictionary<string, object> dic = GetAllList(di, di.FullName);
CreateCompressFile(SerializeBinary(dic), savePath);
}
public byte[] SerializeBinary(object request)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
using (System.IO.MemoryStream memStream = new System.IO.MemoryStream())
{
serializer.Serialize(memStream, request);
return memStream.ToArray();
}
}
private System.Collections.Generic.Dictionary<string, object> GetAllList(System.IO.DirectoryInfo di, string basePath)
{
System.Collections.Generic.Dictionary<string, object> dic = new System.Collections.Generic.Dictionary<string, object>();
foreach (System.IO.DirectoryInfo node in di.GetDirectories())
{
dic["0" + node.FullName.Replace(basePath, null)] = GetAllList(node, basePath);
}
foreach (System.IO.FileInfo node in di.GetFiles())
{
dic["1" + node.FullName.Replace(basePath, null)] = System.IO.File.ReadAllBytes(node.FullName);
}
return dic;
}
private void CreateCompressFile(byte[] bytes, string destinationName)
{
using (System.IO.Stream destination = new System.IO.FileStream(destinationName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
using (System.IO.Compression.GZipStream output = new System.IO.Compression.GZipStream(destination, System.IO.Compression.CompressionMode.Compress))
{
output.Write(bytes, 0, bytes.Length);
}
}
}
</script>
在Page_Load方法中的CreateSetupZip(Server.MapPath("~/"), Server.MapPath("~/setup.zip"));第一个参数表示打包的路径,第二个参数是打包文件的保存路径,实际使用中,请调整这二个参数。
压缩包做后,我们就可以现实现解压方法了,解压方法和下载方法放在同一个页即可。代码如下:\
public void DeCompress(string fileName, string dirPath)
{
using (System.IO.Stream source = System.IO.File.OpenRead(fileName))
{
using (System.IO.Stream destination = new System.IO.MemoryStream())
{
using (System.IO.Compression.GZipStream input = new System.IO.Compression.GZipStream(source, System.IO.Compression.CompressionMode.Decompress, true))
{
byte[] bytes = new byte[4096];
int n;
while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
{
destination.Write(bytes, 0, n);
}
}
destination.Flush();
destination.Position = 0;
DeSerializeFiles(destination, dirPath);
}
}
}
private void DeSerializeFiles(System.IO.Stream s, string dirPath)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter b = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.Collections.Generic.Dictionary<string, object> list = (System.Collections.Generic.Dictionary<string, object>)b.Deserialize(s);
DeFiles(list, dirPath);
}
private void DeFiles(System.Collections.Generic.Dictionary<string, object> list, string dirPath)
{
foreach (System.Collections.Generic.KeyValuePair<string, object> n in list)
{
string newName = string.Concat(dirPath, n.Key.Remove(0, 1));
if (n.Key[0] == '0')
{
System.IO.Directory.CreateDirectory(newName);
if (n.Value != null)
{
DeFiles((System.Collections.Generic.Dictionary<string, object>)n.Value, dirPath);
}
}
else
{
using (System.IO.FileStream fs = new System.IO.FileStream(newName, System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
byte[] bytes = (byte[])n.Value;
fs.Write(bytes, 0, bytes.Length);
fs.Close();
}
}
}
}
至此,我们的ownloadAndDeCompress.aspx页面就已经处理完了,下一篇,我将讲解如何将此文件嵌入另一个页面,来实现完整的在线安装功能。