שתף באמצעות


Unique decompression library for all most-known formats

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.

Composite API examples

Supported Format Table

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"