הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
Question
Sunday, March 30, 2014 12:58 PM
Hi all!
I would like to know if exists a .NET library that can decompress (I don't need to compress) all most-known compression formats (such as ZIP, RAR, 7Z, TAR...).
I've tried the System.IO.Compression.FileSystem namespace and DotNetZip but they seems to only support zip files.
Please help me,
Panda
All replies (9)
Sunday, March 30, 2014 11:38 PM ✅Answered | 1 vote
It's a 418,304 byte .Dll written in C#.
SharpCompress - a fully native C# library for RAR, 7Zip, Zip, Tar, GZip, BZip2
"Project Description
SharpCompress is a compression library for .NET/Mono/Silverlight/WP7 that can unrar, un7zip, unzip, untar unbzip2 and ungzip with forward-only reading and file random access APIs. Write support for zip/tar/bzip2/gzip is implemented.
The major feature is support for non-seekable streams so large files can be processed on the fly (i.e. download stream)."
View source code - SharpCompress.Test
Examples at following link would need to be converted to Visual Basic although you don't state your program is being written in Visual Basic.
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Thursday, April 3, 2014 5:46 PM ✅Answered
Yap, the "Open" method is to used to get an instance
Dim GZipInstance = GZipArchive.Open(stream))
(Dont forget to call "Dispose")
Sunday, March 30, 2014 4:05 PM
You'll need to find, purchase, or create a library to do this. Your best bet is probably to get an API for some other existing archive software that can already handle all of the common formats.
You may be able to do this with 7Zip, at least, you could at one time:
http://www.codeproject.com/Articles/27148/C-NET-Interface-for-Zip-Archive-DLLs
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
Sunday, March 30, 2014 4:23 PM
Hi Reed,
unfortunately I can't get this to work. Any other way?
Thanks
Tuesday, April 1, 2014 6:24 PM
Hi Mr.Monkeyboy!
Thank you for your answer. I've tried SharpCompress and I elaborated, starting from the examples, this code to unpack compressed files:
Select Case IO.Path.GetExtension(fileName)
Case ".zip"
Dim i As SharpCompress.Archive.Zip.ZipArchive
i.WriteToDirectory(tempFilePathName, ExtractOptions.ExtractFullPath Or ExtractOptions.Overwrite)
Case ".rar"
Dim i As SharpCompress.Archive.Rar.RarArchive
i.WriteToDirectory(tempFilePathName, ExtractOptions.ExtractFullPath Or ExtractOptions.Overwrite)
Case ".7z"
Dim i As SharpCompress.Archive.SevenZip.SevenZipArchive
i.WriteToDirectory(tempFilePathName, ExtractOptions.ExtractFullPath Or ExtractOptions.Overwrite)
Case ".tar"
Dim i As SharpCompress.Archive.Tar.TarArchive
i.WriteToDirectory(tempFilePathName, ExtractOptions.ExtractFullPath Or ExtractOptions.Overwrite)
Case ".gzip"
Dim i As SharpCompress.Archive.GZip.GZipArchive
i.WriteToDirectory(tempFilePathName, ExtractOptions.ExtractFullPath Or ExtractOptions.Overwrite)
End Select
But I get a NullReferenceException on i.WriteToDirectory (no matter what format is).
Do you know of any possible solutions?
Thanks,
Panda
Tuesday, April 1, 2014 6:27 PM
That's because i is null. You have declared but not assigned the variable.
eg:
Dim i As new SharpCompress.Archive.Zip.ZipArchive(...)
or
Dim i As SharpCompress.Archive.Zip.ZipArchive(...) = new ...
David
David http://blogs.msdn.com/b/dbrowne/
Tuesday, April 1, 2014 7:27 PM
I haven't tried the library before. Possibly the code below from this link public adamhathcock / sharpcompress converted from C# to VB can provide you some guidance.
Also you can search for code using google or bing or something for that library.
I saw this line also "Dim zip = SharpCompress.Archive.Zip.ZipArchive.Open(fs)" which suggests a file stream contains a zip archive or is going to be used for a zip archive. As davidbaxterbrowne says you appear not to be using the code correctly. But I can't provide a solution either.
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports SharpCompress.Common
Imports SharpCompress.Common.Zip
Imports SharpCompress.Common.Zip.Headers
Imports SharpCompress.Compressor.Deflate
Imports SharpCompress.Reader
Imports SharpCompress.Reader.Zip
Imports SharpCompress.Writer.Zip
Namespace SharpCompress.Archive.Zip
Public Class ZipArchive
Inherits AbstractWritableArchive(Of ZipArchiveEntry, ZipVolume)
Private ReadOnly headerFactory As SeekableZipHeaderFactory
''' <summary>
''' Gets or sets the compression level applied to files added to the archive,
''' if the compression method is set to deflate
''' </summary>
Public Property DeflateCompressionLevel() As CompressionLevel
Get
Return m_DeflateCompressionLevel
End Get
Set
m_DeflateCompressionLevel = Value
End Set
End Property
Private m_DeflateCompressionLevel As CompressionLevel
#If Not PORTABLE AndAlso Not NETFX_CORE Then
''' <summary>
''' Constructor expects a filepath to an existing file.
''' </summary>
''' <param name="filePath"></param>
''' <param name="password"></param>
Public Shared Function Open(filePath As String, Optional password As String = Nothing) As ZipArchive
Return Open(filePath, Options.None, password)
End Function
''' <summary>
''' Constructor with a FileInfo object to an existing file.
''' </summary>
''' <param name="fileInfo"></param>
''' <param name="password"></param>
Public Shared Function Open(fileInfo As FileInfo, Optional password As String = Nothing) As ZipArchive
Return Open(fileInfo, Options.None, password)
End Function
''' <summary>
''' Constructor expects a filepath to an existing file.
''' </summary>
''' <param name="filePath"></param>
''' <param name="options"></param>
''' <param name="password"></param>
Public Shared Function Open(filePath As String, options As Options, Optional password As String = Nothing) As ZipArchive
filePath.CheckNotNullOrEmpty("filePath")
Return Open(New FileInfo(filePath), options, password)
End Function
''' <summary>
''' Constructor with a FileInfo object to an existing file.
''' </summary>
''' <param name="fileInfo"></param>
''' <param name="options"></param>
''' <param name="password"></param>
Public Shared Function Open(fileInfo As FileInfo, options As Options, Optional password As String = Nothing) As ZipArchive
fileInfo.CheckNotNull("fileInfo")
Return New ZipArchive(fileInfo, options, password)
End Function
#End If
''' <summary>
''' Takes a seekable Stream as a source
''' </summary>
''' <param name="stream"></param>
''' <param name="password"></param>
Public Shared Function Open(stream As Stream, Optional password As String = Nothing) As ZipArchive
stream.CheckNotNull("stream")
Return Open(stream, Options.None, password)
End Function
''' <summary>
''' Takes a seekable Stream as a source
''' </summary>
''' <param name="stream"></param>
''' <param name="options"></param>
''' <param name="password"></param>
Public Shared Function Open(stream As Stream, options As Options, Optional password As String = Nothing) As ZipArchive
stream.CheckNotNull("stream")
Return New ZipArchive(stream, options, password)
End Function
#If Not PORTABLE AndAlso Not NETFX_CORE Then
Public Shared Function IsZipFile(filePath As String, Optional password As String = Nothing) As Boolean
Return IsZipFile(New FileInfo(filePath), password)
End Function
Public Shared Function IsZipFile(fileInfo As FileInfo, Optional password As String = Nothing) As Boolean
If Not fileInfo.Exists Then
Return False
End If
Using stream As Stream = fileInfo.OpenRead()
Return IsZipFile(stream, password)
End Using
End Function
#End If
Public Shared Function IsZipFile(stream As Stream, Optional password As String = Nothing) As Boolean
Dim headerFactory As New StreamingZipHeaderFactory(password)
Try
Dim header As ZipHeader = headerFactory.ReadStreamHeader(stream).FirstOrDefault(Function(x) x.ZipHeaderType <> ZipHeaderType.Split)
If header Is Nothing Then
Return False
End If
Return [Enum].IsDefined(GetType(ZipHeaderType), header.ZipHeaderType)
Catch generatedExceptionName As CryptographicException
Return True
Catch
Return False
End Try
End Function
#If Not PORTABLE AndAlso Not NETFX_CORE Then
''' <summary>
''' Constructor with a FileInfo object to an existing file.
''' </summary>
''' <param name="fileInfo"></param>
''' <param name="options"></param>
''' <param name="password"></param>
Friend Sub New(fileInfo As FileInfo, options As Options, Optional password As String = Nothing)
MyBase.New(ArchiveType.Zip, fileInfo, options)
headerFactory = New SeekableZipHeaderFactory(password)
End Sub
Protected Overrides Function LoadVolumes(file As FileInfo, options__1 As Options) As IEnumerable(Of ZipVolume)
If FlagUtility.HasFlag(options__1, Options.KeepStreamsOpen) Then
options__1 = DirectCast(FlagUtility.SetFlag(options__1, Options.KeepStreamsOpen, False), Options)
End If
Return New ZipVolume(file.OpenRead(), options__1).AsEnumerable()
End Function
#End If
Friend Sub New()
MyBase.New(ArchiveType.Zip)
End Sub
''' <summary>
''' Takes multiple seekable Streams for a multi-part archive
''' </summary>
''' <param name="stream"></param>
''' <param name="options"></param>
''' <param name="password"></param>
Friend Sub New(stream As Stream, options As Options, Optional password As String = Nothing)
MyBase.New(ArchiveType.Zip, stream, options)
headerFactory = New SeekableZipHeaderFactory(password)
End Sub
Protected Overrides Function LoadVolumes(streams As IEnumerable(Of Stream), options As Options) As IEnumerable(Of ZipVolume)
Return New ZipVolume(streams.First(), options).AsEnumerable()
End Function
Protected Overrides Function LoadEntries(volumes As IEnumerable(Of ZipVolume)) As IEnumerable(Of ZipArchiveEntry)
Dim volume = volumes.[Single]()
Dim stream As Stream = volume.Stream
For Each h As ZipHeader In headerFactory.ReadSeekableHeader(stream)
If h IsNot Nothing Then
Select Case h.ZipHeaderType
Case ZipHeaderType.DirectoryEntry
If True Then
yield Return New ZipArchiveEntry(Me, New SeekableZipFilePart(headerFactory, TryCast(h, DirectoryEntryHeader), stream))
End If
Exit Select
Case ZipHeaderType.DirectoryEnd
If True Then
Dim bytes As Byte() = TryCast(h, DirectoryEndHeader).Comment
volume.Comment = ArchiveEncoding.[Default].GetString(bytes, 0, bytes.Length)
yield Exit Select
End If
End Select
End If
Next
End Function
Protected Overrides Sub SaveTo(stream As Stream, compressionInfo As CompressionInfo, oldEntries As IEnumerable(Of ZipArchiveEntry), newEntries As IEnumerable(Of ZipArchiveEntry))
Using writer = New ZipWriter(stream, compressionInfo, String.Empty)
For Each entry As var In oldEntries.Concat(newEntries).Where(Function(x) Not x.IsDirectory)
Using entryStream = entry.OpenEntryStream()
writer.Write(entry.Key, entryStream, entry.LastModifiedTime, String.Empty)
End Using
Next
End Using
End Sub
Protected Overrides Function CreateEntryInternal(filePath As String, source As Stream, size As Long, modified As System.Nullable(Of DateTime), closeStream As Boolean) As ZipArchiveEntry
Return New ZipWritableArchiveEntry(Me, source, filePath, size, modified, closeStream)
End Function
Public Shared Function Create() As ZipArchive
Return New ZipArchive()
End Function
Protected Overrides Function CreateReaderForSolidExtraction() As IReader
Dim stream = Volumes.[Single]().Stream
stream.Position = 0
Return ZipReader.Open(stream)
End Function
End Class
End Namespace
'=======================================================
'Service provided by Telerik (www.telerik.com)
'Conversion powered by NRefactory.
'Twitter: @telerik
'Facebook: facebook.com/telerik
'=======================================================
Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.
Thursday, April 3, 2014 3:33 PM
Hi david!
I've tried inserting new, but it says me:
Overload resolution failed because no 'New' is accessible.
Thanks again,
Panda
Thursday, April 3, 2014 4:48 PM
Hi david!
I've tried inserting new, but it says me:
Overload resolution failed because no 'New' is accessible.
Thanks again,
Panda
Then that is not how you are meant to create a new instance of the ZipArchive... look for a factory method like ZipArchive.Open()...
You'll need to follow up on the SharpCompress website with any usage questions as 3rd party software cannot be directly supported here. You should probably close this thread now that you've found some guidance.
Reed Kimble - "When you do things right, people won't be sure you've done anything at all"