Avatar billede jpi Mester
25. januar 2013 - 16:47 Der er 30 kommentarer og
1 løsning

Lave ZIP-filer prgramatisk med undermapper

Hej

Jeg skal lave en zip-fil der indeholder nogle filer som jeg har embedded som en resource samt en tekstfil jeg jeg har som en lang string/StreamWriter.
Nogle af filerne skal ligge i en undermappe.
Er det muligt uden at skulle benytte 3.parts dll'er (Jeg bruger .NET 4.5) og hvordan ?

Hvis ikke er der så et gratis produkt jeg kan benytte ?
Avatar billede olebole Juniormester
25. januar 2013 - 17:21 #1
<ole>

Du kan bruge Shell32

/mvh
</bole>
Avatar billede jpi Mester
25. januar 2013 - 17:40 #2
Det betyder så at jeg skal gemme de embeded resource filer til disken og så lave zip-filen efterfølgende ?

Er der ikke en pænere måde, hvor man ikke laver midlertidige filer ?
Avatar billede olebole Juniormester
25. januar 2013 - 20:03 #3
Du kan prøve at kikke på klassen ZipArchive
Avatar billede jpi Mester
25. januar 2013 - 20:06 #4
Det har jeg gjort, men kan ikke blive klog på om den kan med undermapper eller hvordan jeg skulle gøre det...
Avatar billede olebole Juniormester
25. januar 2013 - 20:17 #5
Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry("Readme.txt")

Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry("mappe\SomeOtherFile.txt")

Der findes ikke mapper i en zip-fil. Der er filer i form af navngivne blokke af binære data - og en liste over disse filers stier. Mapperne bliver først skabt ved udpakningen
Avatar billede olebole Juniormester
25. januar 2013 - 20:19 #6
Njahhh ... to forskellige variabler, selvfølgelig  =)

Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry("Readme.txt")

Dim readmeEntry As ZipArchiveEntry_2 = archive.CreateEntry("mappe\SomeOtherFile.txt")
Avatar billede olebole Juniormester
25. januar 2013 - 20:20 #7
*ROTFL*

Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry("Readme.txt")

Dim readmeEntry_2 As ZipArchiveEntry = archive.CreateEntry("mappe\SomeOtherFile.txt")


Kode og håndbold er en dårlig combo  *D
Avatar billede jpi Mester
25. januar 2013 - 20:40 #8
he he

Kigger på det og vender tilbage. Tak
Avatar billede olebole Juniormester
25. januar 2013 - 21:05 #9
Så fik jeg tid til et eksempel  =)

    Private Sub Zip(fileName As String)
        Dim startBuffer() As Byte = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
        FileIO.FileSystem.WriteAllBytes(fileName, startBuffer, False)

        Using zipToOpen As FileStream = New FileStream(fileName, FileMode.Open)
            Using archive As ZipArchive = New ZipArchive(zipToOpen, ZipArchiveMode.Update)
                Dim readmeEntry As ZipArchiveEntry = archive.CreateEntry("Readme.txt")
                Dim readmeEntry2 As ZipArchiveEntry = archive.CreateEntry("mappe\SomeOtherFile.txt")

                Using writer As StreamWriter = New StreamWriter(readmeEntry.Open())
                    writer.WriteLine("Dette er en fil i roden af zip'en.")
                End Using

                Using writer As StreamWriter = New StreamWriter(readmeEntry2.Open())
                    writer.WriteLine("Dette er en fil i mappen 'mappe'.")
                End Using
            End Using
        End Using
    End Sub
Avatar billede olebole Juniormester
25. januar 2013 - 21:08 #10
PS: Husk en reference til System.IO.Compression
Avatar billede jpi Mester
25. januar 2013 - 22:32 #11
Det virker perfekt.
Men hvad med et billede jeg har som en embedded ressource ?
Avatar billede olebole Juniormester
25. januar 2013 - 23:23 #12
Who cares ... vi er i finalen!  *D

Sorry, det har ikke umiddelbart noget bud på  :o|
Avatar billede arne_v Ekspert
26. januar 2013 - 04:54 #13
Eksempel med baade text og binary entries:

Imports System
Imports System.IO
Imports System.IO.Compression

Namespace E
    Public Class Program
        Private Const REP As Integer = 100
        Public Shared Sub Main(args As String())
            Dim text As String = "This is a little test !!!!"
            Dim buf As Byte() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }
            Using fs As New FileStream("C:\work\sysiocmp.zip", FileMode.Create, FileAccess.Write)
                Using za As New ZipArchive(fs, ZipArchiveMode.Create)
                    Dim tzae As ZipArchiveEntry = za.CreateEntry("xxx/test.txt")
                    Using sw As New StreamWriter(tzae.Open())
                        For i As Integer = 0 To REP - 1
                            sw.WriteLine(text)
                        Next
                    End Using
                    Dim bzae As ZipArchiveEntry = za.CreateEntry("xxx/test.bin")
                    Using s As Stream = bzae.Open()
                        For i As Integer = 0 To REP - 1
                            s.Write(buf, 0, buf.Length)
                        Next
                    End Using
                End Using
            End Using
        End Sub
    End Class
End Namespace
Avatar billede arne_v Ekspert
26. januar 2013 - 04:55 #14
Og det er med vilje at jeg bruger / fremfor \
Avatar billede arne_v Ekspert
26. januar 2013 - 05:12 #15
Samme kode med SharpZipLib:

Imports System
Imports System.IO

Imports ICSharpCode.SharpZipLib.Zip

Namespace E
    Public Class Program
        Private Const REP As Integer = 100
        Public Shared Sub Main(args As String())
            Dim text As String = "This is a little test !!!!"
            Dim buf As Byte() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
            Using fs As New FileStream("C:\work\shrpzplb.zip", FileMode.Create, FileAccess.Write)
                Using zos As New ZipOutputStream(fs)
                    Dim tze As New ZipEntry("xxx/test.txt")
                    zos.PutNextEntry(tze)
                    Dim sw As New StreamWriter(zos)
                    For i As Integer = 0 To REP - 1
                        sw.WriteLine(text)
                    Next
                    sw.Flush() ' do not attempt to close
                    Dim bze As New ZipEntry("xxx/test.bin")
                    zos.PutNextEntry(bze)
                    For i As Integer = 0 To REP - 1
                        zos.Write(buf, 0, buf.Length)
                    Next
                End Using
            End Using
        End Sub
    End Class
End Namespace
Avatar billede arne_v Ekspert
26. januar 2013 - 05:13 #16
SharpZipLib virker saa med alle .NET versioner (den anden kraever .NET 4.5) men kraver saa til gengaeld en ekstern assembly.
Avatar billede jpi Mester
02. februar 2013 - 00:01 #17
Hvordan gemmer man så en fil gemt som ressource som en entry i zip-filen ?

Det er noget i denne blok

Dim bzae As ZipArchiveEntry = za.CreateEntry("xxx/test.bin")
Using s As Stream = bzae.Open()
  For i As Integer = 0 To REP - 1
      s.Write(buf, 0, buf.Length)
  Next
End Using

Tænker at det er noget med denne kommando jeg skal bruge:
My.Resources.ResourceManager.GetStream("tmp.jpg")
men kan ikke få det koblet sammen...
Avatar billede arne_v Ekspert
02. februar 2013 - 00:13 #18
Noget a la:

Dim rs As Stream = My.Resources.ResourceManager.GetStream("tmp.jpg")
Dim bzae As ZipArchiveEntry = za.CreateEntry("xxx/test.bin")
Using s As Stream = bzae.Open()
  Dim n As Integer = rs.Read((buf, 0, buf.Length)
  s.Write(buf, 0, n)
End Using

du boer dog nok have en while loekke omkring Read og Write
Avatar billede jpi Mester
02. februar 2013 - 00:18 #19
Jeg har aldrig rigtig arbejder med streams før, så det med while løkken må du gerne forklare nærmere.

Har du et link til et sted der forklarer, hvorfor buf skal være:
Dim buf As Byte() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}

som du skriver, men olebole bruger:

Dim startBuffer() As Byte = {80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Avatar billede arne_v Ekspert
02. februar 2013 - 00:58 #20
Min var bare for demo.

Du skal bruge:

Dim buf As Byte(10240)

eller tilsvarende
Avatar billede jpi Mester
02. februar 2013 - 01:00 #21
Dim rs As Stream = My.Resources.ResourceManager.GetStream("tmp.jpg")
virker åbenbart heller ikke - rs er tom, selvom der er en fil med navn tmp.jpg som embedded ressource...
Avatar billede arne_v Ekspert
02. februar 2013 - 01:01 #22
while skal vaere noget a la:

        Dim n As Integer
        n = rs.Read(b, 0, b.Length)
        While n > 0
            s.Write(b, 0, n)
            n = rs.Read(b, 0, b.Length)
        End While
Avatar billede jpi Mester
02. februar 2013 - 01:04 #23
Det med while løkken har jeg stadig ikke forstået, og Dim buf as Byte(10240) er ikke gyldigt.

Jeg er ret noob i dette, beklager den manglende forståelse :)
Avatar billede jpi Mester
02. februar 2013 - 01:05 #24
OK, så er løkken på plads - skrev min kommentar efter du havde svaret...
Avatar billede jpi Mester
02. februar 2013 - 13:26 #25
Har fået det til at virke ved at bruge GetManifestResourceStream i stedet. Det er vist noget med hvordan man tilføjer tilen som emdeded resource.
Bruger dog stadig
Dim buf As Byte() = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
da Dim buf as Byte(10240) ikke virker.

Smid et svar begge to, så kan i deles om point
Avatar billede arne_v Ekspert
02. februar 2013 - 16:27 #26
Dim buf As Byte() = New Byte(10240 - 1)
Avatar billede arne_v Ekspert
02. februar 2013 - 16:28 #27
Dim buf As Byte() = New Byte(10240)
Avatar billede arne_v Ekspert
02. februar 2013 - 16:29 #28
og svar
Avatar billede jpi Mester
02. februar 2013 - 16:33 #29
Dim buf As Byte() = New Byte(10240)
virker ikke da Byte ikke har nogen constructor ?
Avatar billede arne_v Ekspert
02. februar 2013 - 16:56 #30
Dim buf As Byte() = New Byte(10240) { }

eller

Dim buf(1023) As Byte
Avatar billede jpi Mester
02. februar 2013 - 17:08 #31
Tak :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester