Benutzer mit den meisten Antworten
Wie auf Zip-Container zugreifen?

Frage
-
Hallo,
unsere Anwendungs-Projekt-Daten bestehen aus mehreren Dateien, die in mehreren Verzeichnissen liegen.
Schön wäre es diese Daten in einer Datei, quasi als Container, weitergeben zu können. Eine Möglichkeit wäre komprimieren in zip o.ä. - wobei es uns nicht aufs Komprimieren ankommt, darauf könnte verzichtet werden. Wichtig wäre das die Dateien zusammen bleiben.
Aber der Zugriff auf die einzelnen Dateien des Projektes soll sich möglichst nicht groß ändern. Auch möchten wir nicht unbedingt mit temporären Dateien arbeiten (alles in ein temp-Verzeichnis packen und mit diesen Dateien arbeiten) da die Daten doch recht groß werden können.
zur Info: Es arbeitet immer nur ein User an den Daten.
Was gibt es hier für Möglichkeiten?
Danke
- Bearbeitet UMorgenw Mittwoch, 29. August 2018 08:26
Mittwoch, 29. August 2018 07:47
Antworten
-
Hi,
die einfachste und transparenteste Lösung ist aus meiner Sicht die Nutzung eines Zip-Archives.… wie macht man das?
Erzeuge ein Zip-Archive und füge dort die Dateien / ByteStream o.ä ein.
Brauche ich da nicht einen Filestream und irgendwie eine Index-Datei, die mir verrät wo ich die entsprechende Datei finde, wenn ich nicht die gesamte Datei scannen möchte?
Du kannst über die Entries-Eigenschaft des Archives, die eine Liste des Inhaltes bereitstellt, das gewünschte Element (Datei / Bild o.ä.) finden.
Früher konnte man unter Delphi mal Records in einer Datei speichern.
Mit dem Zip-Archiv kannst Du dasselbe erreichen.
Dein Link verweist auf die Möglichkeit, unverwaltete Objekte in Strukturen zu kopieren. Dieser Weg unterstützt nach meiner Meinung nicht das Ziel, was Du skizziert hast.
ein schönes Beispiel wäre hilfreich
Hier mal eine kleine Demo einer Konsolenanwendung in VB.NET:
Imports IO = System.IO Imports Comp = System.IO.Compression ' Referenz auf System.IO.Compression Imports System.Text Module Module1 Sub Main() Try Dim c As New Demo c.Execute() Catch ex As Exception Console.WriteLine(ex.Message) End Try Console.WriteLine("weiter mit Taste") Console.ReadKey() End Sub Friend Class Demo Friend Sub Execute() ' Stream erzeugen Dim zipStream As New IO.MemoryStream ' neues Zip-Archiv erzeugen Dim archive As Comp.ZipArchive = CreateZipArchive(zipStream) ' Dateien dem Archiv hinzufügen For i = 1 To 10 Dim str As String = $"Text {i}" Dim bytes As Byte() = Encoding.Default.GetBytes(str) AddBytesToArchive(archive, str, bytes) Next ' Archiv schließen und neu zum Lesen öffnen archive = CloseReopenArchive(archive, zipStream) ' Dateien im Archiv anzeigen For Each name In GetItemNames(archive) Console.WriteLine(name) Next ' Archiv als Datei ablegen SaveZipStream(zipStream, "c:\temp\x.zip") End Sub Private Function CreateZipArchive(stream As IO.Stream) As Comp.ZipArchive Dim archive As New Comp.ZipArchive(stream, Comp.ZipArchiveMode.Create, True) Return archive End Function Private Sub AddBytesToArchive(archiv As Comp.ZipArchive, name As String, b As Byte()) Dim entry As Comp.ZipArchiveEntry = archiv.CreateEntry(name) 'entry. Using writer As IO.BinaryWriter = New IO.BinaryWriter(entry.Open()) writer.Write(b, 0, b.Length) End Using End Sub Private Function CloseReopenArchive(archiv As Comp.ZipArchive, stream As IO.Stream) As Comp.ZipArchive archiv.Dispose() Return New Comp.ZipArchive(stream, Comp.ZipArchiveMode.Read, True) End Function Private Iterator Function GetItemNames(archive As Comp.ZipArchive) As IEnumerable(Of String) For Each item As Comp.ZipArchiveEntry In archive.Entries Yield item.Name Next End Function Private Sub SaveZipStream(zipStream As IO.Stream, path As String) zipStream.Position = 0 Using writer As IO.FileStream = New IO.FileStream(path, IO.FileMode.Create) zipStream.CopyTo(writer) End Using End Sub End Class End Module
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks- Bearbeitet Peter Fleischer Dienstag, 4. September 2018 07:05
- Als Antwort vorgeschlagen Peter Fleischer Dienstag, 4. September 2018 07:05
- Als Antwort markiert Stefan FalzModerator Dienstag, 27. November 2018 17:27
Dienstag, 4. September 2018 07:04
Alle Antworten
-
Hi,
Du wirst in allen Varianten nicht drumrum kommen, die Dateien irgendwie zu kopieren. Für das Zusammenhalten (auch ohne Komprimierung) kannst Du bspw. DotNetZip nehmen.
Ich frage mich nur, warum Du das so machen willst?
Wenn es darum geht, dass ein User mit der Anwendung arbeitet, dann alles zusammenpackt, an einen anderen User übermittelt und der soll dann weiterarbeiten, würde ich wie oben geschrieben, DotNetZip integrieren, eine Methode zum Packen und Versenden aller relevanter Dateien und je nach gewünschter Vorgehensweise dann noch das Gegenstück dazu (also entpacken in die Zielordner) einbauen.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, RemotesupportMittwoch, 29. August 2018 08:27Moderator -
Hi,
es muss kein temporärer Ordner sein, Du kannst ja bspw. auch mit MemoryStreams arbeiten und die Dateien so aus der Zip Datei lesen und wieder speichern.
Docx, ... sind letztendlich auch nur Zip Dateien. Wie genau da aber der interne Mechanismus zum Lesen und schreiben der enthaltenen Dateien ist, weiß ich nicht.
Gruß, Stefan
Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, RemotesupportMittwoch, 29. August 2018 12:56Moderator -
Moin,
mal angenommen, ich möchte 100.000 Bilder in einer Datei abspeichern (komprimieren erstmal nicht nötig) und später die Bilder laden und anzeigen, evtl noch nach Bildern mit bestimmter Bezeichnung suchen - wie macht man das?
Brauche ich da nicht einen Filestream und und irgendwie eine Index-Datei, die mir verrät wo ich die entsprechende Datei finde, wenn ich nicht die gesamte Datei scannen möchte?
Früher konnte man unter Delphi mal Records in einer Datei speichern.
Hiermit geht das offenbar auch, mit allen Nachteilen:
https://msdn.microsoft.com/de-de/library/4ca6d5z7%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
ein schönes Beispiel wäre hilfreich...
Freitag, 31. August 2018 10:44 -
Hallo,
man möge die *.c -Sources von Mark Adler anwenden, die Mühe diese in einer eigen Lib zu Kompilieren lohnt.
https://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/lxr/source/src/util/compress/zlib/
Grüße
Karsten Schulz
- Bearbeitet Karsten.Schulz Montag, 3. September 2018 22:59
Montag, 3. September 2018 22:56 -
Hi,
die einfachste und transparenteste Lösung ist aus meiner Sicht die Nutzung eines Zip-Archives.… wie macht man das?
Erzeuge ein Zip-Archive und füge dort die Dateien / ByteStream o.ä ein.
Brauche ich da nicht einen Filestream und irgendwie eine Index-Datei, die mir verrät wo ich die entsprechende Datei finde, wenn ich nicht die gesamte Datei scannen möchte?
Du kannst über die Entries-Eigenschaft des Archives, die eine Liste des Inhaltes bereitstellt, das gewünschte Element (Datei / Bild o.ä.) finden.
Früher konnte man unter Delphi mal Records in einer Datei speichern.
Mit dem Zip-Archiv kannst Du dasselbe erreichen.
Dein Link verweist auf die Möglichkeit, unverwaltete Objekte in Strukturen zu kopieren. Dieser Weg unterstützt nach meiner Meinung nicht das Ziel, was Du skizziert hast.
ein schönes Beispiel wäre hilfreich
Hier mal eine kleine Demo einer Konsolenanwendung in VB.NET:
Imports IO = System.IO Imports Comp = System.IO.Compression ' Referenz auf System.IO.Compression Imports System.Text Module Module1 Sub Main() Try Dim c As New Demo c.Execute() Catch ex As Exception Console.WriteLine(ex.Message) End Try Console.WriteLine("weiter mit Taste") Console.ReadKey() End Sub Friend Class Demo Friend Sub Execute() ' Stream erzeugen Dim zipStream As New IO.MemoryStream ' neues Zip-Archiv erzeugen Dim archive As Comp.ZipArchive = CreateZipArchive(zipStream) ' Dateien dem Archiv hinzufügen For i = 1 To 10 Dim str As String = $"Text {i}" Dim bytes As Byte() = Encoding.Default.GetBytes(str) AddBytesToArchive(archive, str, bytes) Next ' Archiv schließen und neu zum Lesen öffnen archive = CloseReopenArchive(archive, zipStream) ' Dateien im Archiv anzeigen For Each name In GetItemNames(archive) Console.WriteLine(name) Next ' Archiv als Datei ablegen SaveZipStream(zipStream, "c:\temp\x.zip") End Sub Private Function CreateZipArchive(stream As IO.Stream) As Comp.ZipArchive Dim archive As New Comp.ZipArchive(stream, Comp.ZipArchiveMode.Create, True) Return archive End Function Private Sub AddBytesToArchive(archiv As Comp.ZipArchive, name As String, b As Byte()) Dim entry As Comp.ZipArchiveEntry = archiv.CreateEntry(name) 'entry. Using writer As IO.BinaryWriter = New IO.BinaryWriter(entry.Open()) writer.Write(b, 0, b.Length) End Using End Sub Private Function CloseReopenArchive(archiv As Comp.ZipArchive, stream As IO.Stream) As Comp.ZipArchive archiv.Dispose() Return New Comp.ZipArchive(stream, Comp.ZipArchiveMode.Read, True) End Function Private Iterator Function GetItemNames(archive As Comp.ZipArchive) As IEnumerable(Of String) For Each item As Comp.ZipArchiveEntry In archive.Entries Yield item.Name Next End Function Private Sub SaveZipStream(zipStream As IO.Stream, path As String) zipStream.Position = 0 Using writer As IO.FileStream = New IO.FileStream(path, IO.FileMode.Create) zipStream.CopyTo(writer) End Using End Sub End Class End Module
--
Viele Grüsse
Peter Fleischer (ehem. MVP)
Meine Homepage mit Tipps und Tricks- Bearbeitet Peter Fleischer Dienstag, 4. September 2018 07:05
- Als Antwort vorgeschlagen Peter Fleischer Dienstag, 4. September 2018 07:05
- Als Antwort markiert Stefan FalzModerator Dienstag, 27. November 2018 17:27
Dienstag, 4. September 2018 07:04