读书人

C# 解压缩文件?解决办法

发布时间: 2012-03-27 13:44:24 作者: rapoo

C# 解压缩文件?
C# 如何解压缩文件?大家用的什么方法?

在网上看到用SharpZipLib,但是下载的例子都是压缩可以,解压不可以的。

我要压缩的是文件夹,文件夹下有很多子文件夹,和文件。大概20M

目前用的这种方法,但是效率太慢了,6.7M的zip文件解压的制定目录差不多要1分钟,有点受不了。

这个方法是:

C# code
//添加引用Shell32.dll 在系统文件夹里public bool BuildFrame(string srcFile, string destFolder)        {            try            {                Shell32.ShellClass sc = new Shell32.ShellClass();                Shell32.Folder SrcFolder = sc.NameSpace(srcFile);                Shell32.Folder DestFolder = sc.NameSpace(destFolder);                Shell32.FolderItems items = SrcFolder.Items();                DestFolder.CopyHere(items, 20);                return true;            }            catch            {                return false;            }        }


这个方法运行可以,就是太慢1分多种,请问大家有其他办法没?


希望能运行的,最好是源码,不要贴网上的,网上的都参考的差不多了。

谢谢了

[解决办法]
直接调用WINR
[解决办法]
解压本来就是要看你文件的大小的啊。。
[解决办法]
你去下载一个组件 ICSharpCode.SharpZipLib.dll

下面是我写的包装方法。
你看一下,满不满 足你的要求
C# code
 
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using ICSharpCode.SharpZipLib.Zip;

namespace Microsoft.ITF.Tools.GZIP
{
public class GZip
{
/// <summary>
/// 打包文件
/// </summary>
/// <param name="filenames">要打包的文件列表 </param>
/// <param name="GzipFileName">目标文件名 </param>
/// <param name="CompressionLevel">压缩品质级别(0~9) </param>
/// <param name="SleepTimer">休眠时间(单位毫秒) </param>
public static void DoZip( List <FileInfo> filenames, string GzipFileName, int CompressionLevel, int SleepTimer )
{

ZipOutputStream s = new ZipOutputStream( File.Create( GzipFileName ) );
try
{
s.SetLevel( CompressionLevel ); //0 - store only to 9 - means best compression

foreach ( FileInfo file in filenames )
{
FileStream fs = null;
try
{
fs = file.Open( FileMode.Open, FileAccess.ReadWrite );
}
catch
{ continue; }

byte[] buffer = new byte[fs.Length];
fs.Read( buffer, 0, buffer.Length );

ZipEntry entry = new ZipEntry( Path.GetFileName( file.Name ) );
entry.DateTime = ( file.CreationTime > file.LastWriteTime ? file.LastWriteTime : file.CreationTime );

s.PutNextEntry( entry );

s.Write( buffer, 0, buffer.Length );


fs.Close();
file.Delete();

if ( SleepTimer > 10 )
Thread.Sleep( SleepTimer );
}
}
finally
{
s.Finish();
s.Close();
}
}
/// <summary>
/// 打包文件
/// </summary>
/// <param name="filenames">要打包的文件列表 </param>
/// <param name="GzipFileName">目标文件名 </param>
/// <param name="CompressionLevel">压缩品质级别(0~9) </param>
/// <param name="SleepTimer">休眠时间(单位毫秒) </param>
public static void DoZip( List <string> filenames, string GzipFileName, int CompressionLevel, int SleepTimer )
{
ZipOutputStream s = new ZipOutputStream( File.Create( GzipFileName ) );


try
{
s.SetLevel( CompressionLevel ); //0 - store only to 9 - means best compression

foreach ( string filename in filenames )
{
FileInfo file = new FileInfo( filename );
FileStream fs = null;
try
{
fs = file.Open( FileMode.Open, FileAccess.ReadWrite );
}
catch
{ continue; }

byte[] buffer = new byte[fs.Length];
fs.Read( buffer, 0, buffer.Length );

ZipEntry entry = new ZipEntry( Path.GetFileName( file.Name ) );
entry.DateTime = ( file.CreationTime > file.LastWriteTime ? file.LastWriteTime : file.CreationTime );

s.PutNextEntry( entry );

s.Write( buffer, 0, buffer.Length );


fs.Close();
file.Delete();

if ( SleepTimer > 10 )
Thread.Sleep( SleepTimer );
}
}
finally
{
s.Finish();
s.Close();
}
}
/// <summary>
/// 解压缩文件
/// </summary>
/// <param name="GzipFile">压缩包文件名 </param>
/// <param name="dPath">解压路径 </param>
public static void UnZip( string GzipFile, string dPath )
{
ZipInputStream s = new ZipInputStream( File.OpenRead( GzipFile ) );

string directoryName = Path.GetDirectoryName( dPath + "\\" ) + "\\";

if ( !Directory.Exists( directoryName ) ) Directory.CreateDirectory( directoryName );//生成解压目录
string CurrentDirectory = directoryName;

byte[] data = new byte[2048];
int size = 2048;

ZipEntry theEntry = null;
FileStream streamWriter = null;
while ( ( theEntry = s.GetNextEntry() ) != null )
{
if ( theEntry.IsDirectory )
{// 该结点是目录
if ( !Directory.Exists( CurrentDirectory + theEntry.Name ) ) Directory.CreateDirectory( CurrentDirectory + theEntry.Name );
}
else
{
if ( theEntry.Name != String.Empty )
{
//解压文件到指定的目录
streamWriter = File.Create( CurrentDirectory + theEntry.Name );
while ( true )
{
size = s.Read( data, 0, data.Length );
if ( size <= 0 ) break;

streamWriter.Write( data, 0, size );
}
streamWriter.Close();
}
}
}
s.Close();
}
}
}


[解决办法]
C# 压缩类 - ZipClass.cs
C# code
 
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Text;
using System.IO;
using System.IO.Compression;

//压缩类
class ZipClass
{
//压缩方法-----------------------------------------
public void CompressFile ( string sourceFile, string destinationFile )
{
// make sure the source file is there
if ( File.Exists ( sourceFile ) == false )
throw new FileNotFoundException ( );

// Create the streams and byte arrays needed
byte[] buffer = null;
FileStream sourceStream = null;
FileStream destinationStream = null;
GZipStream compressedStream = null;

try
{
// Read the bytes from the source file into a byte array
sourceStream = new FileStream ( sourceFile, FileMode.Open, FileAccess.Read, FileShare.Read );



// Read the source stream values into the buffer
buffer = new byte[sourceStream.Length];
int checkCounter = sourceStream.Read ( buffer, 0, buffer.Length );

if ( checkCounter != buffer.Length )
{
throw new ApplicationException ( );
}

// Open the FileStream to write to
destinationStream = new FileStream ( destinationFile, FileMode.OpenOrCreate, FileAccess.Write );

// Create a compression stream pointing to the destiantion stream
compressedStream = new GZipStream ( destinationStream, CompressionMode.Compress, true );

// Now write the compressed data to the destination file
compressedStream.Write ( buffer, 0, buffer.Length );

}
catch ( ApplicationException ex )
{
MessageBox.Show ( ex.Message, "压缩文件时发生错误:", MessageBoxButtons.OK, MessageBoxIcon.Error );

}
finally
{
// Make sure we allways close all streams
if ( sourceStream != null ) sourceStream.Close();
if ( compressedStream != null ) compressedStream.Close();
if ( destinationStream != null ) destinationStream.Close();
}
}

//解压-----------------------------------------
public void DecompressFile ( string sourceFile, string destinationFile )
{
// make sure the source file is there
if ( File.Exists ( sourceFile ) == false ) throw new FileNotFoundException();

// Create the streams and byte arrays needed
FileStream sourceStream = null;
FileStream destinationStream = null;
GZipStream decompressedStream = null;
byte[] quartetBuffer = null;

try
{
// Read in the compressed source stream
sourceStream = new FileStream ( sourceFile, FileMode.Open );

// Create a compression stream pointing to the destiantion stream
decompressedStream = new GZipStream ( sourceStream, CompressionMode.Decompress, true );

// Read the footer to determine the length of the destiantion file
quartetBuffer = new byte[4];
int position = (int)sourceStream.Length - 4;
sourceStream.Position = position;
sourceStream.Read ( quartetBuffer, 0, 4 );
sourceStream.Position = 0;
int checkLength = BitConverter.ToInt32 ( quartetBuffer, 0 );

byte[] buffer = new byte[checkLength + 100];

int offset = 0;
int total = 0;

// Read the compressed data into the buffer
while ( true )
{
int bytesRead = decompressedStream.Read ( buffer, offset, 100 );
if ( bytesRead == 0 ) break;

offset += bytesRead;
total += bytesRead;
}

// Now write everything to the destination file
destinationStream = new FileStream ( destinationFile, FileMode.Create );


destinationStream.Write ( buffer, 0, total );

// and flush everyhting to clean out the buffer
destinationStream.Flush ( );
}
catch ( ApplicationException ex )
{
MessageBox.Show(ex.Message, "解压文件时发生错误:", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
{
// Make sure we allways close all streams
if ( sourceStream != null ) sourceStream.Close();
if ( decompressedStream != null ) decompressedStream.Close();
if ( destinationStream != null ) destinationStream.Close();
}

}
}


[解决办法]
直接调用WinRaR才是王道,否则你打算怎么处理大文件呢?对于4G以上的大文件压缩,总不能先使用文件流一次性加载后压缩吧,内存都会不够的。至少我还没有看到过可以进行分段压缩的,都是对整个文件流的压缩,内存显然是不够用。

读书人网 >C#

热点推荐