对字符串或文件的压缩和解压Tool

/**********************************************************
* CJF Development Library for Microsoft.NET
* Note:对字符串或文件的压缩和解压
* Create Date:2011-11-15
* Author:崔俊峰
* Copyright (c) 2012,2015 Cjf Studio.China
* All Rigths Reserved!
**********************************************************/

using System;
using System.IO;
using System.Text;
using System.Data;
using System.Text.RegularExpressions;
using System.Runtime.Serialization.Formatters.Binary;
using ICSharpCode.SharpZipLib.Zip;
using Cjf.Components.Security.Crc;

namespace Cjf.Tool
{
/// <summary>
/// 对字符串或文件的压缩和解压
/// </summary>
public class ZipLib
{
/// <summary>
/// 使用SharpZipLib压缩Zip文件 Zip与UnZip对应
/// </summary>
/// <param name="srcFile">源文件</param>
/// <param name="dstFile">压缩后的Zip文件</param>
public static void Zip(string srcFile, string dstFile)
{
Zip(srcFile, dstFile, 8096);
}

// <summary>
/// 使用SharpZipLib解压缩Zip文件
/// </summary>
/// <param name="srcFile">Zip源文件</param>
/// <param name="dstFile">解压出来的文件</param>
public static void UnZip(string srcFile, string dstFile)
{
UnZip(srcFile, dstFile, 8096);
}

/// <summary>
/// 使用SharpZipLib压缩Zip文件 Zip与UnZip对应
/// </summary>
/// <param name="srcFile">源文件</param>
/// <param name="dstFile">压缩后的Zip文件</param>
/// <param name="bufferSize">缓冲大小</param>
public static void Zip(string srcFile, string dstFile, int bufferSize)
{
using (FileStream fileStreamIn = new FileStream(srcFile, FileMode.Open, FileAccess.Read))
{
using (FileStream fileStreamOut = File.Create(dstFile))
{
using (ZipOutputStream zipOutStream = new ZipOutputStream(fileStreamOut))
{
byte[] buffer = new byte[bufferSize];
ZipEntry entry = new ZipEntry(Path.GetFileName(srcFile));
zipOutStream.PutNextEntry(entry);
int size;
do
{
size = fileStreamIn.Read(buffer, 0, buffer.Length);
zipOutStream.Write(buffer, 0, size);
} while (size > 0);
zipOutStream.Flush();
}
}
}
}

/// <summary>
/// 使用SharpZipLib解压缩Zip文件 Zip与UnZip对应
/// </summary>
/// <param name="srcFile">Zip源文件</param>
/// <param name="dstFile">解压出来的文件</param>
/// <param name="bufferSize">缓冲大小</param>
public static void UnZip(string srcFile, string dstFile, int bufferSize)
{
using (FileStream fileStreamIn = new FileStream(srcFile, FileMode.Open, FileAccess.Read))
{
using (ZipInputStream zipInStream = new ZipInputStream(fileStreamIn))
{
ZipEntry entry = zipInStream.GetNextEntry();
using (FileStream fileStreamOut = new FileStream(dstFile + @"\s" + entry.Name, FileMode.Create, FileAccess.Write))
{
int size;
byte[] buffer = new byte[bufferSize];
do
{
size = zipInStream.Read(buffer, 0, buffer.Length);
fileStreamOut.Write(buffer, 0, size);
} while (size > 0);
fileStreamOut.Flush();
}
}
}
}

/// <summary>
/// 测试Zip文件是否完整
/// </summary>
/// <param name="srcFile">Zip源文件</param>
/// <returns></returns>
public static bool Test(string srcFile)
{
bool flag = false;
using (ZipFile zf = new ZipFile(srcFile))
{
flag = zf.TestArchive(true);
}
return flag;
}

/// <summary>
/// 压缩文件到16进制字符串
/// ZipFileToHexString与UnZipHexStringToFile对应
/// </summary>
/// <param name="aFilePath"></param>
/// <param name="aHexString"></param>
/// <param name="aShowErrorMsg"></param>
/// <returns></returns>
public static bool ZipFileToHexString(string aFilePath, out string aHexString, bool aShowErrorMsg = false)
{
bool bReturn = false;
string path = aFilePath + "_=_";
FileStream fs = null;
aHexString = "";

try
{
if (File.Exists(aFilePath) == false)
throw new Exception("文件:" + aFilePath + " 不存在!");
Zip(aFilePath, path);
if (Test(path) == false)
throw new Exception("压缩后的文件:" + path + " 不完整!");
fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] byteArray = new byte[fs.Length];
int count = fs.Read(byteArray, 0, (int)fs.Length);
if (count != byteArray.Length)
throw new Exception("文件的长度与读取到的长度不相等!");
CRC32 crc = new CRC32();
aHexString = StringTool.ArrayToHexString(byteArray);
aHexString = crc.GetCrc(aHexString) + "," + aHexString; //加入校验码
bReturn = true;
}
catch (Exception ex)
{
if (aShowErrorMsg)
{
while (ex.InnerException != null)
ex = ex.InnerException;
Msg.MessageBox_Error(ex.Message);
}
}
finally
{
if (fs != null) { fs.Close(); fs.Dispose(); };
File.Delete(path);
}

return bReturn;
}

/// <summary>
/// 将16进制字符串解压为文件 ZipFileToHexString与UnZipHexStringToFile对应
/// </summary>
/// <param name="aHexString"></param>
/// <param name="aPath"></param>
/// <param name="aBufferSize"></param>
/// <param name="aShowErrorMsg"></param>
/// <returns></returns>
public static bool UnZipHexStringToFile(string aHexString, string aPath,bool aShowErrorMsg = false)
{
bool bReturn = false;
if (string.IsNullOrEmpty(aHexString) || string.IsNullOrEmpty(aPath))
return false;

try
{
CRC32 crc = new CRC32();
int pos=aHexString.IndexOf(',');
string s=aHexString.Substring(0, pos); //取得校验码
aHexString = aHexString.Substring(pos + 1);
if (s != crc.GetCrc(aHexString).ToString())
throw new Exception("数据不完整!");

using (MemoryStream fileStreamIn = new MemoryStream(StringTool.HexStringToArray(aHexString)))
{
using (ZipInputStream zipInStream = new ZipInputStream(fileStreamIn))
{
ZipEntry entry = zipInStream.GetNextEntry();
using (FileStream fileStreamOut = new FileStream(aPath + "\\" + entry.Name, FileMode.Create, FileAccess.Write))
{
int size;
byte[] buffer = new byte[8096];
do
{
size = zipInStream.Read(buffer, 0, buffer.Length);
fileStreamOut.Write(buffer, 0, size);
} while (size > 0);
fileStreamOut.Flush();
bReturn = true;
}
}
}
}
catch (Exception ex)
{
if (aShowErrorMsg)
{
while (ex.InnerException != null)
ex = ex.InnerException;
Msg.MessageBox_Error(ex.Message);
}
}
return bReturn;
}

/// <summary>
/// 将Datatable进行序列化后再压缩返回16进制字符串
/// ZipDataTableToHexString与UnZipHexStringToDataTable对应
/// </summary>
/// <param name="aTable"></param>
/// <returns></returns>
public static string ZipDataTableToHexString(DataTable aTable)
{
string s = StringTool.SerializerToXml(aTable);
if (string.IsNullOrEmpty(s))
return "";
byte[] b = Encoding.Unicode.GetBytes(s);
b = Compress(b);
return StringTool.ArrayToHexString(b);
}

/// <summary>
/// 将序列化后16进制字符串反序列为Datatable
/// ZipFileToHexString与UnZipHexStringToFile对应
/// </summary>
/// <param name="aHexString"></param>
/// <returns></returns>
public static DataTable UnZipHexStringToDataTable(string aHexString)
{
if (string.IsNullOrEmpty(aHexString))
return null;
aHexString = Encoding.Unicode.GetString(Decompress(StringTool.HexStringToArray(aHexString)));
return StringTool.DeSerializerFromXml(aHexString);
}

/// <summary>
/// 对指定的字符串进行压缩,如果源串的长度太短(小于1000),不建议压缩,因为压缩后要添加特征字符后,
/// 要比源串要长,得不到想要的效果 Compress与Decompress对应
/// </summary>
/// <param name="aString"></param>
/// <returns></returns>
public static string Compress(string aString)
{
if (string.IsNullOrEmpty(aString))
return "";
StringBuilder sb = new StringBuilder();
byte[] byteArray = Compress(Encoding.Unicode.GetBytes(aString));
foreach (byte item in byteArray)
sb.Append((char)item);
return sb.ToString();
}

/// <summary>
/// 对指定的压缩字符串进行解压 Compress与Decompress对应
/// </summary>
/// <param name="aString"></param>
/// <returns></returns>
public static string Decompress(string aString)
{
if (string.IsNullOrEmpty(aString))
return "";

int indexBA = 0;
byte[] byteArray = new byte[aString.Length];
foreach (char item in aString.ToCharArray())
byteArray[indexBA++] = (byte)item;

return Encoding.Unicode.GetString(Decompress(byteArray));
}

/// <summary>
/// 对字节数组进行压缩 Compress与Decompress对应
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static byte[] Compress(byte[] bytes)
{
using (MemoryStream ms = new MemoryStream())
{
System.IO.Compression.GZipStream Compress = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);
Compress.Write(bytes, 0, bytes.Length);
Compress.Close();
return ms.ToArray();
}
}

/// <summary>
/// 对压缩的字节数组进行解压 Compress与Decompress对应
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static byte[] Decompress(Byte[] bytes)
{
using (MemoryStream tempMs = new MemoryStream())
{
using (MemoryStream ms = new MemoryStream(bytes))
{
System.IO.Compression.GZipStream Decompress = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);
int indexBA = 0;
while (true)
{
//分次解压,因为取不到GZipStream流的长度,它不支持
indexBA = Decompress.Read(bytes, 0, bytes.Length);
if (indexBA == 0)
break;
tempMs.Write(bytes, 0, indexBA);
}
//tempMs.Flush();
Decompress.Close();
return tempMs.ToArray();
}
}
}

/// <summary>
/// 对指定的文件进行压缩,成功返回true,并置aZipStr为压缩后的字符串,否则返回false
/// ZipFile与UnZipToTile对应
/// </summary>
/// <param name="aFilePath"></param>
/// <param name="aZipStr"></param>
/// <param name="aShowErrorMsg"></param>
/// <returns></returns>
public static bool ZipFile(string aFilePath,out string aZipStr,bool aShowErrorMsg=false)
{
bool bReturn = false;
aZipStr = "";

FileStream fs = null;
System.IO.MemoryStream ms = null;
System.IO.Compression.GZipStream sw=null;

try
{
if (File.Exists(aFilePath)==false)
throw new Exception("文件:" + aFilePath + " 不存在!");

fs = new FileStream(aFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] byteArray = new byte[fs.Length];
int count=fs.Read(byteArray, 0, (int)fs.Length) ;
if (count != byteArray.Length)
throw new Exception("文件的长度与读取到的长度不相等!");

//准备压缩
ms = new System.IO.MemoryStream();
sw = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Compress);

//压缩
sw.Write(byteArray, 0, byteArray.Length);
sw.Close(); sw.Dispose(); //必须立即关闭,否则取得的字节数不对

//byte[] aa = ms.ToArray();
//aZipStr = StringTool.ArrayToHexString(ms.ToArray());
//byte[] bb = StringTool.HexStringToArray(aZipStr);
//转换 byte[] zip 数据到字符串
byteArray = ms.ToArray();
System.Text.StringBuilder sB = new System.Text.StringBuilder(byteArray.Length);
foreach (byte item in byteArray)
sB.Append((char)item);

//aZipStr = sB.ToString();
aZipStr = StringTool.ArrayToHexString(ms.ToArray());
bReturn = true;
}
catch (Exception ex)
{
if (aShowErrorMsg)
{
while (ex.InnerException != null)
ex = ex.InnerException;
Msg.MessageBox_Error(ex.Message);
}
}
finally
{
if (fs != null) { fs.Close(); fs.Dispose(); };
if (sw != null) { sw.Close(); sw.Dispose(); };
if (ms != null) { ms.Close(); ms.Dispose(); };
}

return bReturn;
}

/// <summary>
/// 对指定的压缩字符串进行解压并保存到指定的文件,成功返回true,否则返回false
/// ZipFile与UnZipToTile对应
/// </summary>
/// <param name="aZipStr"></param>
/// <param name="aFilePath"></param>
/// <param name="aShowErrorMsg"></param>
/// <returns></returns>
public static bool UnZipToTile(string aZipStr, string aFilePath, bool aShowErrorMsg = false)
{
bool bReturn = false;
FileStream fs = null;
System.IO.MemoryStream ms = null;
System.IO.Compression.GZipStream sr = null;

if (string.IsNullOrEmpty(aZipStr) || string.IsNullOrEmpty(aFilePath))
return false;
byte[] byteArray = StringTool.HexStringToArray(aZipStr);
int indexBA = 0;

try
{
//准备解压
fs = new FileStream(aFilePath, FileMode.Create);
ms = new System.IO.MemoryStream(byteArray);
sr = new System.IO.Compression.GZipStream(ms, System.IO.Compression.CompressionMode.Decompress);

while (true)
{
//分次解压,因为取不到GZipStream流的长度,它不支持
indexBA = sr.Read(byteArray, 0, byteArray.Length);
if (indexBA == 0)
break;
fs.Write(byteArray, 0, indexBA);
}

fs.Flush();
bReturn = true;
}
catch (Exception ex)
{
if (aShowErrorMsg)
{
while (ex.InnerException != null)
ex = ex.InnerException;
Msg.MessageBox_Error(ex.Message);
}
}
finally
{
if (fs != null) { fs.Close(); fs.Dispose(); };
if (sr != null) { sr.Close(); sr.Dispose(); };
if (ms != null) { ms.Close(); ms.Dispose(); };
}

return bReturn;
}
}
}

posted @ 2017-03-15 10:45  我在码头等你  阅读(232)  评论(0编辑  收藏  举报