想拥有一个自己的压缩算法实现很久了,但直到net2.0微软才开始提供官方的压缩算法。并且激动永远只是短暂的,作为智能开发的这一片,我们仿佛总是处于遗忘的角落。Net Compact framework (以下简单ncf) 1.0是不必说了,那是一个玩具,绝不是工具!ncf2有了较大改观,可以说这开始成为一种工具了。我们拥有了更多的功能,com的部分支持(但没有ActiveX控件及一些完整Com的功能)。但在System.IO命名空间,失望的我也没有找到Compression空间。。。
在对微软无视使用net精简版的我的需求,我在表达了最强烈的愤慨后,无奈地接受了这一现实。但我实在无法接受等待下一版ncf3的漫长等待,也许等待永远都意味着失望。我决定用行动改变这一切!
我查阅了net2的MSIL源程序,虽然逆向工程并不是一件伟大的事,但我认为我根据net完整版的源程序帮微软提供NCF2的扩充功能对微软应该不是什么坏事8)
System.IO.Compression处于net完整版那臃肿的system.dll中,接下来的事就不细说了,我痛苦地copy/paste并删除了一些ncf2不支持的属性,并将System.SR类合并入这个空间中,4 个小时后,我生成了和完整版功能一模一样的CECompression.dll(当然是一模一样啦,程序都是微软写的,我只是负责修正8))象普罗米修斯从宙斯控制下偷火一样,我将System.IO.Compression带到了幸福的智能开发世界。
在这儿你可以获得这个dll/Files/DreamlikeAttic/CECompression.rar。至于使用嘛,在项目中添加对这个dll的引用就可以了,帮助看msdn对System.IO.Compression的说明就行。。。。
这此我也提供一个使用这个dll的实用程序,可以对指定的源文件进行(压缩/解压缩)后得到目标文件。
完整代码如下:
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 testGzip
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void menuItem1_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnSelectSource_Click(object sender, EventArgs e)
{
dlgFileOpen.FileName = "";
DialogResult tdlgResult = dlgFileOpen.ShowDialog();
if (tdlgResult == DialogResult.OK)
txtSource.Text = dlgFileOpen.FileName;
//end if
}//end sub
private void btnSelectDest_Click(object sender, EventArgs e)
{
dlgSaveFile.FileName = "";
DialogResult tdlgResult = dlgSaveFile.ShowDialog();
if (tdlgResult == DialogResult.OK)
txtDest.Text = dlgSaveFile.FileName;
//end if
}
private void btnZip_Click(object sender, EventArgs e)
{
//开始压缩
//先验证源文件名及目标文件名的正确性
if (System.IO.File.Exists(txtSource.Text) == false)
{
MessageBox.Show("源文件名指定的文件不存在");
txtSource.Focus();
return;
}//end if
if (System.IO.File.Exists(txtDest.Text) == true)
{
DialogResult tdlgResult = MessageBox.Show("指定的目标文件已存在,覆盖吗?",
"文件覆盖确认", MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
if (tdlgResult == DialogResult.No)
{
txtDest.Focus();
return;
}
}//endif
bool tblnResult = FileGZipCompress(txtSource.Text, txtDest.Text);
if (tblnResult == false)
MessageBox.Show("压缩出现错误!压缩失败");
//end if
}//end sub
bool FileGZipCompress(string ni_strSourceFile, string ni_strDestFile)
{
FileStream tobjSourceFileStream;
MessageBox.Show("开始对"+txtSource.Text +"进行文件压缩");
try
{
// Open the file as a FileStream object.
tobjSourceFileStream = new FileStream(ni_strSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] taSourcebuffer = new byte[tobjSourceFileStream.Length];
// Read the file to ensure it is readable.
int count = tobjSourceFileStream.Read(taSourcebuffer, 0, taSourcebuffer.Length);
if (count != taSourcebuffer.Length)
{
tobjSourceFileStream.Close();
MessageBox.Show("压缩失败,不能读取指定的文件");
return false ;
}
tobjSourceFileStream.Close();
FileStream tobjDestFileStream = new FileStream(ni_strDestFile,FileMode.Create,FileAccess.ReadWrite );// new MemoryStream();
MemoryStream tobjMemStream = new MemoryStream();
// 使用内存流进行压缩
GZipStream compressedzipStream = new GZipStream(tobjMemStream, CompressionMode.Compress, true);
Cursor.Current = Cursors.WaitCursor;
//向压缩流写入要压缩的数据
compressedzipStream.Write(taSourcebuffer, 0, taSourcebuffer.Length);
//关闭压缩流
compressedzipStream.Close();
//此处应该写入文件头信息,在此处简单写入一个文件长度
tobjDestFileStream.Position = 0;
tobjDestFileStream.Write(BitConverter.GetBytes(taSourcebuffer.Length),0,4);//写入4字节的文件长度
//定入压缩得到的实际数据
tobjMemStream.WriteTo(tobjDestFileStream);
tobjMemStream.Close();
Cursor.Current = Cursors.Default;
MessageBox.Show("压缩完成.源文件大小为:\n" + taSourcebuffer.Length + "字节\n"
+ "压缩后大小为" + tobjDestFileStream.Length + "字节\n"
+ "压缩比为: " + (tobjDestFileStream.Length / taSourcebuffer.Length*100)+" %");
tobjDestFileStream.Close();
return true;
}
catch
{
return false;
}//end try
}//end sub
private bool FileGZipDecompress(string ni_strSourceFile, string ni_strDestFile)
{
//对指定的压缩文件进行解压缩
FileStream tobjSourceFileStream;
GZipStream tobjGzipStream = null;
MemoryStream tobjMemStream ;
try
{
Cursor.Current = Cursors.WaitCursor;
tobjSourceFileStream = new FileStream(ni_strSourceFile, FileMode.Open, FileAccess.Read, FileShare.Read);
//取得文件的原始长度
byte[] tabytFileLength=new byte[4];
tobjSourceFileStream.Read(tabytFileLength,0,4);
int tintFileLength = BitConverter.ToInt32(tabytFileLength,0);
byte[] tabyteDeCompressData=new byte[tobjSourceFileStream.Length-4];
tobjSourceFileStream.Read(tabyteDeCompressData, 0, tabyteDeCompressData.Length);
tobjMemStream = new MemoryStream(tabyteDeCompressData);
tobjGzipStream = new GZipStream(tobjMemStream, CompressionMode.Decompress);
byte[] tabytBuffer = new byte[tintFileLength];
tobjGzipStream.Read( tabytBuffer, 0, tintFileLength );
tobjGzipStream.Close();
tobjSourceFileStream.Close();
//将压缩的数据写入目标文件
FileStream tobjDestFileStream = new FileStream(ni_strDestFile, FileMode.Create, FileAccess.ReadWrite,
FileShare.None);
tobjDestFileStream.Write(tabytBuffer, 0, tabytBuffer.Length);
tobjDestFileStream.Close();
Cursor.Current = Cursors.Default;
return true;
}
catch
{
return false;
}//end try
}//end sub
private void btnUnzip_Click(object sender, EventArgs e)
{
//开始解压缩
//先验证源文件名及目标文件名的正确性
if (System.IO.File.Exists(txtSource.Text) == false)
{
MessageBox.Show("源文件名指定的文件不存在");
txtSource.Focus();
return;
}//end if
if (System.IO.File.Exists(txtDest.Text) == true)
{
DialogResult tdlgResult = MessageBox.Show("指定的目标文件已存在,覆盖吗?",
"文件覆盖确认", MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button1);
if (tdlgResult == DialogResult.No)
{
txtDest.Focus();
return;
}
}//endif
MessageBox.Show("开始对\"" + txtSource.Text + "\"进行文件解压缩");
bool tblnResult = FileGZipDecompress(txtSource.Text, txtDest.Text);
if (tblnResult == false)
MessageBox.Show("解压缩出现错误!解压缩失败");
else
MessageBox.Show("解压缩成功完成");
//end if
}//end sub
}//end class
}//end namespace
你可以这儿获取相应的源程序包:/Files/DreamlikeAttic/CECompressionTest.rar
如移动设备开发感兴趣可以加入以下群24123368
入群需知:
1、不是编程开发人员请勿加入。
2、没时间讨论问题或喜欢潜水的请勿加入。
3、只想获得源程序的请勿加入
本blog文档,未经作者同意,谢绝转载。谢谢你对我的blog的访问.
联系方式: missilecat@163.com QQ:85403578