您的位置:首页 > 其它

GZipstream压缩解压文件夹方法2

2009-01-17 01:41 399 查看
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Compression;

namespace WinAppTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private const string m_FileExtensionName = ".XXzip"; // hwzip compress file
private const int m_MaxFileTotalLength = 1024 * 1024 * 1024; // 1G
private const int m_ReadBufferSize = 8 * 1024; // 8K

private string m_GZipFileName = string.Empty;
private string m_FolderDecompressTo = string.Empty;

private List<TGZipFileEntry> m_FileEntryList = new List<TGZipFileEntry>();
private List<TGZipFileEntry> m_PacketEntryList = new List<TGZipFileEntry>();

private byte[] m_ReadBuffer = new byte[m_ReadBufferSize];

private int m_NowMaxBarValue = 0;

private void btnOpen_Click(object sender, EventArgs e)
{
FolderBrowserDialog browser = new FolderBrowserDialog();
if (browser.ShowDialog() == DialogResult.OK)
{
txtPath.Text = browser.SelectedPath;
}
}

private void btnCompress_Click(object sender, EventArgs e)
{
try
{
string filePath = txtPath.Text.Trim() + "//";
string fileName = txtFileName.Text.Trim();
if (filePath.Length == 0 || fileName.Length == 0) return;

// GZipCompress.Compress(filePath, fileName);
Compressing(fileName, filePath);
MessageBox.Show("Success");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void btnOpenSaveAs_Click(object sender, EventArgs e)
{
SaveFileDialog save = new SaveFileDialog();
save.AddExtension = true;
save.Filter = "Gzip|*.Gzip";

if (save.ShowDialog() == DialogResult.OK)
{
txtFileName.Text = save.FileName;
}
}

//

public bool AppendFile(string fileName)
{
if (string.IsNullOrEmpty(fileName) || !File.Exists(fileName))
{
MessageBox.Show("Zip FileName is empty or does not exist.");
return false;
}

TGZipFileEntry addFileInfo = new TGZipFileEntry(fileName);
long totalLength = addFileInfo.OriginalLength;

foreach (TGZipFileEntry fileEntry in m_FileEntryList)
{
if (fileEntry.FileName.ToUpper() == addFileInfo.FileName.ToUpper())
{
MessageBox.Show("File: " + fileEntry.FileName + " has exists.");
return false;
}
totalLength += fileEntry.OriginalLength;
}

if (totalLength > m_MaxFileTotalLength)
{
MessageBox.Show("Total files length is over " + (m_MaxFileTotalLength / (1024 * 1024)).ToString() + "M.");
return false;
}

m_FileEntryList.Add(addFileInfo);
return true;
}

private bool Compressing(string zipFileName,string path)
{
m_FileEntryList.Clear();

foreach (string str in Directory.GetFiles(path))
{
AppendFile(str);
}

bool opSuccess = false;

if (m_FileEntryList.Count == 0)
{
MessageBox.Show("There has no compress file.");
return opSuccess;
}
m_GZipFileName = zipFileName;
if (string.IsNullOrEmpty(m_GZipFileName))
{
MessageBox.Show("Zip FileName is empty or not set.");
return opSuccess;
}

this.SetApplicationCursor(Cursors.WaitCursor);

try
{
using (FileStream outStream = new FileStream(m_GZipFileName, FileMode.Create, FileAccess.Write, FileShare.None))
{
this.m_PacketEntryList.Clear();
this.WriteHeaderEmptyInfo(outStream); // 写文件长度字节, 压缩结束后再填实际数据
this.SetProgressBarMaxValue(false);
this.ShowBeginStep();

foreach (TGZipFileEntry fileEntry in m_FileEntryList)
{
this.SetProgressBarNowMaxValue(fileEntry, false);

fileEntry.WriteEntryInfo(outStream);
this.ShowProgressStep();
this.CompressFile(fileEntry, outStream);
this.m_PacketEntryList.Add(fileEntry);
}

this.WriteHeaderLengthInfo(outStream); // 再填文件头, 此时有各块的长度信息
}
opSuccess = true;
}
catch (Exception err)
{
throw new Exception(err.Message);
}
finally
{
this.ShowFinalStep();
this.SetApplicationCursor(Cursors.Default);
}
return opSuccess;
}

/// <summary>
/// Compress one file.
/// </summary>
private void CompressFile(TGZipFileEntry fileEntry, Stream outStream)
{
long preStreamPosition = outStream.Position;

using (FileStream srcStream = new FileStream(fileEntry.FileFullName, FileMode.Open, FileAccess.Read, FileShare.Read))
using (GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress, true))
{
this.ShowProgressStep();

int readCount = m_ReadBufferSize;
while (readCount == m_ReadBufferSize)
{
readCount = srcStream.Read(m_ReadBuffer, 0, m_ReadBufferSize);
zipStream.Write(m_ReadBuffer, 0, readCount);

this.ShowProgressStep();
}
}

fileEntry.GZipFileLength = (int)(outStream.Position - preStreamPosition); // 写入的长度
}

/// <summary>
/// 写空头字节, 用于占位置
/// </summary>
private void WriteHeaderEmptyInfo(Stream outStream)
{
int headerSize = 1 + m_FileEntryList.Count * 3; // 前4个字节是文件数, 每个文件3部分, 分别是: 原文件长、压缩后长、文件项长
byte[] headerBytes = new byte[4 * headerSize];
outStream.Write(headerBytes, 0, headerBytes.Length);
}

/// <summary>
/// 写实际的文件数、文件长度、项长度字节
/// </summary>
private void WriteHeaderLengthInfo(Stream outStream)
{
byte[] fileCountBytes = BitConverter.GetBytes((int)m_PacketEntryList.Count);
TCipher.EncryptBytes(fileCountBytes);

outStream.Position = 0;
outStream.Write(fileCountBytes, 0, fileCountBytes.Length);

foreach (TGZipFileEntry entry in m_PacketEntryList)
{
entry.WriteLengthInfo(outStream);
}
}

///////////

private bool Decompressing(string zipFileName,string decompressFolder)
{
bool opSuccess = false;
m_FolderDecompressTo = decompressFolder;
if (string.IsNullOrEmpty(m_FolderDecompressTo))
{
MessageBox.Show("Decompress folder is empty.");
return opSuccess;
}
m_GZipFileName = zipFileName;
if (string.IsNullOrEmpty(m_GZipFileName))
{
MessageBox.Show("Zip FileName is empty or does not exist.");
return opSuccess;
}

this.SetApplicationCursor(Cursors.WaitCursor);

try
{
using (FileStream srcStream = new FileStream(m_GZipFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
this.m_PacketEntryList.Clear();
this.ReadHeaderLengthInfo(srcStream); // 获得各块的长度信息, 缺少文件项中的文件名、日期等信息
this.SetProgressBarMaxValue(true);
this.ShowBeginStep();

foreach (TGZipFileEntry fileEntry in m_PacketEntryList)
{
this.SetProgressBarNowMaxValue(fileEntry, true);

fileEntry.ReadEntryInfo(srcStream); // 读当前项的日期、文件名信息
this.ShowProgressStep();
this.DecompressFile(srcStream, fileEntry);
fileEntry.ResetFileDateTime(m_FolderDecompressTo);
}
}
opSuccess = true;
}
catch (Exception err)
{
throw new Exception(err.Message);
}
finally
{
this.ShowFinalStep();
this.SetApplicationCursor(Cursors.Default);
}

return opSuccess;
}

private void DecompressFile(Stream srcStream, TGZipFileEntry fileEntry)
{
using (FileStream outStream = new FileStream(this.m_FolderDecompressTo + fileEntry.FileName, FileMode.Create, FileAccess.Write, FileShare.None))
using (MemoryStream memStream = new MemoryStream())
using (GZipStream zipStream = new GZipStream(memStream, CompressionMode.Decompress, true))
{
int gzipFileLength = fileEntry.GZipFileLength;
int readCount;
while (gzipFileLength > 0)
{
int maxCount = Math.Min(gzipFileLength, m_ReadBufferSize);

readCount = srcStream.Read(m_ReadBuffer, 0, maxCount);
memStream.Write(m_ReadBuffer, 0, readCount);

gzipFileLength -= readCount;

this.ShowProgressStep();
}

memStream.Position = 0;
readCount = m_ReadBufferSize;
while (readCount == m_ReadBufferSize)
{
readCount = zipStream.Read(m_ReadBuffer, 0, m_ReadBufferSize);
outStream.Write(m_ReadBuffer, 0, readCount);

this.ShowProgressStep();
}
}
this.ShowProgressStep();
}

private void ReadHeaderLengthInfo(Stream srcStream)
{
byte[] fileCountBytes = new byte[4];
srcStream.Read(fileCountBytes, 0, fileCountBytes.Length);
TCipher.EncryptBytes(fileCountBytes);

int fileCount = BitConverter.ToInt32(fileCountBytes, 0);

for (int k = 1; k <= fileCount; k++)
{
TGZipFileEntry entry = new TGZipFileEntry();
entry.ReadLengthInfo(srcStream);
m_PacketEntryList.Add(entry);
}
}

private void btnDecompress_Click(object sender, EventArgs e)
{
try
{
string filePath = txtPath.Text.Trim();
string fileName = txtFileName.Text.Trim();
if (filePath.Length == 0 || fileName.Length == 0) return;

// GZipCompress.Compress(filePath, fileName);
Decompressing(fileName, filePath);
MessageBox.Show("Success");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}

}

/////////

/// <summary>
/// 设置当前控件及其全部父控件的光标
/// </summary>
private void SetApplicationCursor(Cursor cursor)
{
this.Cursor = cursor;
Control parent = this.Parent;
while (parent != null)
{
parent.Cursor = cursor;
parent = parent.Parent;
}
}

private void SetStartPosition()
{
this.progressBar1.Value = 0;
this.progressBar1.Refresh();
}

private void ShowBeginStep()
{
this.progressBar1.Value += 1;
this.progressBar1.Refresh();
}

private void ShowProgressStep()
{
if (this.progressBar1.Value + 1 < m_NowMaxBarValue)
{
this.progressBar1.Value += 1;
}
}

private void ShowFinalStep()
{
while (this.progressBar1.Value + 1 < this.progressBar1.Maximum)
{
this.progressBar1.Value += 1;
}
this.progressBar1.Value = this.progressBar1.Maximum;
this.progressBar1.Refresh();
}

private int GetFileMaxStepLength(TGZipFileEntry fileEntry, bool decompress)
{
int maxLength = Math.Max(fileEntry.OriginalLength, fileEntry.GZipFileLength);
int stepValue = 0;

if (decompress)
{
stepValue++; // 取文件项
stepValue += 2 * (maxLength / m_ReadBufferSize); // 产生压缩流
stepValue++; // 关闭文件
}
else
{
stepValue++; // 打开源文件
stepValue++; // 写文件信息项
stepValue += maxLength / m_ReadBufferSize; // 压缩
}

return stepValue;
}

private void SetProgressBarMaxValue(bool decompress)
{
this.SetStartPosition();
m_NowMaxBarValue = 0;

int maxBarValue = 1; // 打开/建立文件
if (decompress)
{
foreach (TGZipFileEntry fileEntry in m_PacketEntryList)
{
maxBarValue += this.GetFileMaxStepLength(fileEntry, decompress); // 加每个文件的步长
}
}
else
{
foreach (TGZipFileEntry fileEntry in m_FileEntryList)
{
maxBarValue += this.GetFileMaxStepLength(fileEntry, decompress); // 加每个文件的步长
}
}
maxBarValue += 1; // 最后收尾
this.progressBar1.Maximum = maxBarValue;
}

private void SetProgressBarNowMaxValue(TGZipFileEntry fileEntry, bool decompress)
{
m_NowMaxBarValue += this.GetFileMaxStepLength(fileEntry, decompress);
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: