SwanKnight

Zipper

Apr 19th, 2015
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 10.17 KB | None | 0 0
  1. Imports System.IO
  2. Imports System.IO.Compression
  3.  
  4. Public Class Zipper
  5.     Public Event Progress(percent As Integer)    
  6.     Public Event StatusChanged(status As String)
  7.     Public Event Complete()
  8.     Public Event Canceled()
  9.  
  10.     Public Enum Overwrite
  11.         Always
  12.         Never
  13.     End Enum
  14.  
  15.     Private _cancel As Boolean
  16.  
  17.     Public Property Cancel As Boolean
  18.         Get
  19.             Return _cancel
  20.         End Get
  21.         Set(value As Boolean)
  22.             If _cancel = True Then Exit Property
  23.             _cancel = value
  24.         End Set
  25.     End Property
  26.  
  27.     Private _compression As CompressionLevel
  28.     Public Property CompressionLevel As CompressionLevel
  29.         Get
  30.             Return _compression
  31.         End Get
  32.         Set(value As CompressionLevel)
  33.             _compression = value
  34.         End Set
  35.     End Property
  36.  
  37.     Private _target As String
  38.     Public Property TargetURL As String
  39.         Get
  40.             Return _target
  41.         End Get
  42.         Set(value As String)
  43.             _target = value
  44.         End Set
  45.     End Property
  46.  
  47.     Private _source As String
  48.     Public Property SourceURL As String
  49.         Get
  50.             Return _source
  51.         End Get
  52.         Set(value As String)
  53.             _source = value
  54.         End Set
  55.     End Property
  56.  
  57.     Private _isDir As Boolean
  58.     Public ReadOnly Property SourceIsDirectory
  59.         Get
  60.             Return _isDir
  61.         End Get
  62.     End Property
  63.  
  64.     Private _includeRootDir As Boolean
  65.     Public Property IncludeRootDir As Boolean
  66.         Get
  67.             Return _includeRootDir
  68.         End Get
  69.         Set(value As Boolean)
  70.             _includeRootDir = value
  71.         End Set
  72.     End Property
  73.  
  74.     Private _overwrite As Overwrite
  75.     Private _sessionLength As Int64
  76.     Private _sessionFiles As String()
  77.     Private _rootDir As String
  78.  
  79.     Private Function GetSessionLength() As Int64
  80.         Dim sLen As Int64 = 0
  81.         For Each sessionFile As String In _sessionFiles
  82.             sLen += New FileInfo(sessionFile).Length
  83.             If Cancel = True Then Exit For
  84.         Next
  85.         Return sLen
  86.     End Function
  87.  
  88.     Private Function GetEntriesLength() As Int64
  89.         Dim sLen As Int64 = _sessionFiles.Sum(Function(file) New FileInfo(file).Length)      
  90.         Return sLen
  91.     End Function
  92.  
  93.     Private Function IsDir(source As String) As Int16
  94.         If File.Exists(source) Then
  95.             Return 0
  96.         ElseIf Directory.Exists(source) Then
  97.             Return -1
  98.         Else
  99.             Return 1
  100.         End If
  101.     End Function
  102.  
  103.     Private Function InlineAssignHelper(Of T)(ByRef target As T, value As T) As T
  104.         target = value
  105.         Return value
  106.     End Function
  107.  
  108.     Public Sub Compress(source As String, target As String, compressionLevel As CompressionLevel, overwrite As Overwrite)
  109.         RaiseEvent StatusChanged("Gathering required information")
  110.  
  111.         _overwrite = False
  112.         _includeRootDir = True
  113.         _target = target
  114.         _compression = compressionLevel
  115.         _cancel = False
  116.  
  117.         If IsDir(source) <> 1 Then
  118.             _isDir = IsDir(source)
  119.             _source = source
  120.         Else
  121.             Throw New Exception("Source file or directory doesn't exist or cannot be accessed.")
  122.         End If
  123.  
  124.         If SourceIsDirectory Then
  125.             _sessionFiles = Directory.GetFiles(SourceURL, "*", SearchOption.AllDirectories)
  126.         Else
  127.             _sessionFiles = New String() {SourceURL}
  128.         End If
  129.  
  130.         RaiseEvent StatusChanged("Examining files")
  131.  
  132.         _sessionLength = GetSessionLength()
  133.  
  134.         If SourceIsDirectory And IncludeRootDir = False Then
  135.             _rootDir = SourceURL & "\"
  136.         Else
  137.             _rootDir = String.Join("\", SourceURL.Split("\").ToArray, _
  138.                                    0, SourceURL.Split("\").ToArray.Length - 1) & "\"
  139.         End If
  140.  
  141.         RaiseEvent StatusChanged("Compressing")
  142.  
  143.         Try
  144.             Zip()
  145.         Catch ex As Exception
  146.             MsgBox(ex.Message)
  147.             Exit Sub
  148.         End Try
  149.  
  150.         If Cancel = True Then
  151.             RaiseEvent Canceled()
  152.             RaiseEvent StatusChanged("Cancelled")
  153.             RaiseEvent Progress(100)
  154.         Else
  155.             RaiseEvent Complete()
  156.             RaiseEvent StatusChanged("Complete")
  157.         End If
  158.     End Sub
  159.  
  160.     Public Sub Decompress(source As String, target As String, overwrite As Overwrite)
  161.         RaiseEvent StatusChanged("Gathering required information")
  162.  
  163.         _overwrite = overwrite
  164.         _source = source
  165.         _cancel = False
  166.         _target = target
  167.  
  168.         RaiseEvent StatusChanged("Examining files")
  169.  
  170.         _sessionLength = GetEntriesLength()
  171.  
  172.         RaiseEvent StatusChanged("Decompressing")
  173.  
  174.         Try
  175.             Unzip()
  176.         Catch ex As Exception
  177.             MsgBox(ex.Message)
  178.             Exit Sub
  179.         End Try
  180.  
  181.         If Cancel = True Then
  182.             RaiseEvent Canceled()
  183.             RaiseEvent StatusChanged("Cancelled")
  184.             RaiseEvent Progress(100)
  185.         Else
  186.             RaiseEvent Complete()
  187.             RaiseEvent StatusChanged("Complete")
  188.         End If
  189.     End Sub
  190.  
  191.     Private Sub Zip()
  192.         If Cancel = True Then Exit Sub
  193.         Dim blockSizeToRead As Int32 = 1048576 '1Mib Buffer
  194.         Dim buffer As Byte() = New Byte(blockSizeToRead - 1) {}
  195.         Dim bytesRead As Int64, totalBytesRead As Int64
  196.         Dim liveProg As Int16 = 0
  197.         Dim prevProg As Int16 = 0
  198.  
  199.         If File.Exists(_target) And _overwrite = Overwrite.Never Then
  200.             Throw New Exception("Target file already exists")
  201.         Else
  202.             File.Delete(_target)
  203.         End If
  204.  
  205.         Using fs As FileStream = New FileStream(_target, FileMode.CreateNew, FileAccess.Write)
  206.             Using archive As ZipArchive = New ZipArchive(fs, ZipArchiveMode.Create)
  207.                 Dim entry As ZipArchiveEntry = Nothing
  208.                 For Each sessionFile As String In _sessionFiles
  209.                     Try
  210.                         Using reader As FileStream = File.Open(sessionFile, FileMode.Open, FileAccess.Read)
  211.                             entry = archive.CreateEntry(sessionFile.Replace(_rootDir, ""), _compression)
  212.                             Using writer As Stream = entry.Open()
  213.                                 While (InlineAssignHelper(bytesRead, _
  214.                                     reader.Read(buffer, 0, buffer.Length - 1))) > 0
  215.                                     writer.Write(buffer, 0, bytesRead)
  216.                                     totalBytesRead += bytesRead
  217.                                     liveProg = CInt((100 / _sessionLength) * totalBytesRead)
  218.  
  219.                                     If liveProg <> prevProg Then
  220.                                         prevProg = liveProg
  221.                                         RaiseEvent Progress(liveProg)
  222.                                     End If
  223.                                     If Cancel = True Then Exit While
  224.                                 End While
  225.                             End Using
  226.                         End Using
  227.                     Catch ex As Exception
  228.                         totalBytesRead += New FileInfo(sessionFile).Length
  229.                         Console.WriteLine(String.Format("Unable to add file to archive: {0} Error:{1}", sessionFile, ex.Message))
  230.                     End Try
  231.                     If Cancel = True Then Exit For
  232.                 Next
  233.             End Using
  234.         End Using
  235.         If Cancel = True Then
  236.             File.Delete(_target)
  237.         End If
  238.     End Sub
  239.  
  240.     Private Sub Unzip()
  241.         If Cancel = True Then Exit Sub
  242.         Dim blockSizeToRead As Int32 = 1048576 '1Mib Buffer
  243.         Dim buffer As Byte() = New Byte(blockSizeToRead - 1) {}
  244.         Dim bytesRead As Int64, totalBytesRead As Int64
  245.         Dim liveProg As Int16 = 0
  246.         Dim prevProg As Int16 = 0
  247.  
  248.         Using fs As FileStream = New FileStream(_source, FileMode.Open)
  249.             Using archive As ZipArchive = New ZipArchive(fs, ZipArchiveMode.Read)
  250.                 For Each entry As ZipArchiveEntry In archive.Entries
  251.                     Dim output As String = String.Format("{0}{1}\{2}", _target, _
  252.                                                             Path.GetFileNameWithoutExtension(_source), _
  253.                                                             entry.FullName.Replace("/", "\"))
  254.  
  255.                     Dim directoryPath As String = IIf(output.EndsWith("\"), output, Directory.GetParent(output).ToString)
  256.  
  257.                     If output.EndsWith("\") Then
  258.                         Continue For
  259.                     Else
  260.                         If File.Exists(output) Then
  261.                             Select Case _overwrite
  262.                                 Case Overwrite.Always
  263.                                     File.Delete(output)
  264.                                 Case Overwrite.Never
  265.                                     Throw New Exception("Target file already exists")
  266.                             End Select
  267.                         End If
  268.                     End If
  269.  
  270.                     If Directory.Exists(directoryPath) = False Then
  271.                         Directory.CreateDirectory(directoryPath)
  272.                     End If
  273.  
  274.                     Using reader As Stream = entry.Open()
  275.                         Using writer As FileStream = New FileStream(output, FileMode.Create)
  276.                             While (InlineAssignHelper(bytesRead, reader.Read(buffer, 0, buffer.Length - 1))) > 0
  277.                                 writer.Write(buffer, 0, bytesRead)
  278.                                 totalBytesRead += bytesRead
  279.                                 liveProg = CInt((100 / _sessionLength) * totalBytesRead)
  280.                                 If liveProg <> prevProg Then
  281.                                     prevProg = liveProg
  282.                                     RaiseEvent Progress(liveProg)
  283.                                 End If
  284.                                 If Cancel = True Then Exit While
  285.                             End While
  286.                         End Using
  287.                     End Using
  288.                     If Cancel = True Then Exit For
  289.                 Next
  290.             End Using
  291.         End Using
  292.     End Sub
  293. End Class
Add Comment
Please, Sign In to add comment