Verzeichnisse komprimieren

  • VB.NET

Es gibt 13 Antworten in diesem Thema. Der letzte Beitrag () ist von Kagurame.

    Verzeichnisse komprimieren

    Hallo zusammen,

    ich habe ein Problem. Ich möchte ein ganzes Verzeichnis archivieren. Um Speicherplatz zu sparen, möchte ich es komprimieren (wie ein Zip-Archiv).
    Da habe ich dieses Snippet gefunden (dotnet-snippets.de/dns/ordner-komprimierung-SID563.aspx)

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System.IO
    2. .............
    3. Private Const COMPRESSION_FORMAT_NONE As Short = 0
    4. Private Const COMPRESSION_FORMAT_LZNT1 As Short = 2
    5. Private Const FSCTL_SET_COMPRESSION As Integer = 639040
    6. Private Const FILE_SHARE_NONE As Short = 0
    7. Private Const OPEN_EXISTING As Short = 3
    8. Private Const INVALID_HANDLE_VALUE As Short = -1
    9. Private Const GENERIC_READ As Integer = &H80000000
    10. Private Const GENERIC_WRITE As Integer = &H40000000
    11. Private Const FILE_FLAG_BACKUP_SEMANTICS As Integer = &H2000000
    12. Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" _
    13. (ByVal lpFileName As String, _
    14. ByVal dwDesiredAccess As Integer, _
    15. ByVal dwShareMode As Integer, _
    16. ByVal lpSecurityAttributes As IntPtr, _
    17. ByVal dwCreationDisposition As Integer, _
    18. ByVal dwFlagsAndAttributes As Integer, _
    19. ByVal hTemplateFile As IntPtr) As IntPtr
    20. Private Declare Function CloseHandle Lib "kernel32" _
    21. (ByVal hObject As IntPtr) As Boolean
    22. Private Declare Function DeviceIoControl Lib "kernel32" _
    23. (ByVal hDevice As IntPtr, _
    24. ByVal dwIoControlCode As Integer, _
    25. ByRef lpInBuffer As Short, _
    26. ByVal nInBufferSize As Short, _
    27. ByVal lpOutBuffer As Integer, _
    28. ByVal nOutBufferSize As Integer, _
    29. ByRef lpBytesReturned As Integer, _
    30. ByVal lpOverlapped As IntPtr) As Boolean
    31. Private Sub CompressFolder(ByVal fullpath As String)
    32. Dim Files() As FileInfo
    33. Dim Subfolders() As DirectoryInfo
    34. Dim CurrentFolder As DirectoryInfo
    35. SetCompressionState(fullpath)
    36. CurrentFolder = New DirectoryInfo(fullpath)
    37. Try
    38. Files = CurrentFolder.GetFiles()
    39. For Each CurrentFile As FileInfo In Files
    40. With CurrentFile
    41. If .Attributes And FileAttributes.ReadOnly Then
    42. ' Schreibschutzattribut vorübergehend entfernen
    43. .Attributes = .Attributes And Not FileAttributes.ReadOnly
    44. .Refresh()
    45. CompressFile(.FullName)
    46. ' Schreibschutzattribut wieder setzen
    47. .Attributes = .Attributes Or FileAttributes.ReadOnly
    48. .Refresh()
    49. Else
    50. CompressFile(.FullName)
    51. End If
    52. End With
    53. Next
    54. Catch
    55. '
    56. End Try
    57. Try
    58. Subfolders = CurrentFolder.GetDirectories()
    59. For Each Subfolder As DirectoryInfo In Subfolders
    60. fullpath = Subfolder.FullName & "\"
    61. CompressFolder(fullpath)
    62. Next
    63. Catch
    64. '
    65. End Try
    66. End Sub
    67. Private Sub SetCompressionState(ByVal folder As String)
    68. Dim Size As Short = 2
    69. Dim ReturnedBytes As Integer
    70. Dim Result As Boolean
    71. Dim Handle As IntPtr
    72. Handle = CreateFile(folder, _
    73. GENERIC_READ Or GENERIC_WRITE, _
    74. FILE_SHARE_NONE, _
    75. IntPtr.Zero, _
    76. OPEN_EXISTING, _
    77. FILE_FLAG_BACKUP_SEMANTICS, _
    78. IntPtr.Zero)
    79. If Handle.ToInt32 <> INVALID_HANDLE_VALUE Then
    80. Result = DeviceIoControl(Handle, _
    81. FSCTL_SET_COMPRESSION, _
    82. COMPRESSION_FORMAT_LZNT1, _
    83. Size, _
    84. 0, _
    85. 0, _
    86. ReturnedBytes, _
    87. IntPtr.Zero)
    88. CloseHandle(Handle)
    89. End If
    90. End Sub
    91. Private Sub CompressFile(ByVal file As String)
    92. Dim Size As Short = 2
    93. Dim ReturnedBytes As Integer
    94. Dim Result As Boolean
    95. Dim Stream As FileStream
    96. Try
    97. Stream = New FileStream(file, FileMode.Open, _
    98. FileAccess.ReadWrite, FileShare.None)
    99. Result = DeviceIoControl(Stream.Handle, _
    100. FSCTL_SET_COMPRESSION, _
    101. COMPRESSION_FORMAT_LZNT1, _
    102. Size, _
    103. 0, _
    104. 0, _
    105. ReturnedBytes, _
    106. IntPtr.Zero)
    107. Stream.Close()
    108. Catch
    109. If Not Stream Is Nothing Then
    110. Stream.Close()
    111. End If
    112. End Try
    113. End Sub
    114. -------------------------------------------------
    115. Beispiel : CompressFolder("C:\Temp")


    Bei mir zeigt es keine Fehlermeldung an, doch es spuckt auch nichts komprimiertes aus.
    Wird da überhaupt was komprimiert? Und wenn ja, wohin?

    Vielen Dank :D

    Rolandos

    rolandos schrieb:

    Wird da überhaupt was komprimiert? Und wenn ja, wohin?
    Sollen wir jetzt für Dich den von Dir gefundenen Code analysieren und nach Fehlern durchflöhen :?: :thumbdown:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Du kannst ja mal deren Namen bei Google befragen, die MSDN ist auch eine gute Adresse, da solltest Du mal loslegen. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    also ich kann schomal sagen, dass der Code Crap ist.

    Betrachte einfach mal die Zeilen #46 - #69:

    VB.NET-Quellcode

    1. Try
    2. '...allerlei Code, der nun machen kann, wasserwill, ohne dass je ein Fehler bemerkt werden kann
    3. Catch
    4. End Try
    Wer TryCatchens derart verwendet, gehört eigentlich sicherheits-verwahrt, denner ist eine Gefahr für die Öffentlichkeit ;)

    gugge vlt. TryCatch ist ein heißes Eisen
    ja, genau das ist das Problem, dass du keine Fehler angezeigt bekommst.
    Vermutlich treten nämlich doch welche auf, aber wegen dieser gemeingefährlichen TryCatches bekommst du sie nicht angezeigt.
    Ergo: Du wirst die Fehler niemals beheben können.

    Wie gesagt: vergiss das Snippet, und probier was anneres - vlt. dieses hier: (Un-)Zippen ohne Zusatz-Komponente
    Mach als Minimallösung bei Catch eine MessageBox rein, dass Du wenigstens gesagt bekommst, dass was geknallt hat. Und dann sieh Dir die Exception genau an.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Allgemeiner Hinweiß:
    Während dem Debuggenam besten folgendes machen:

    VS: Debug => Exceptions => Bei Thrown überall ein haken machen, mindestens aber bei Common Language Runtime Exceptions
    Sorgt dafür, dass beim Debuggen Try Catch ignoriert wird und die Exceptions trotzdem rausgehaun werden, dann brauchste nichmal gucken ob irgendein Baka die Exceptions alle auffrisst.