Laden...

SharpZipLib Memorystream als Datei hinzufügen ohne andere Dateien zu löschen.

Erstellt von Cornflake vor 8 Jahren Letzter Beitrag vor 8 Jahren 968 Views
C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren
SharpZipLib Memorystream als Datei hinzufügen ohne andere Dateien zu löschen.

Hallo Leute

Inzwischen kann ich einen String über Memorystream als Datei in eine Zipdatei speichern. Ich verwende .NET 3.5 mit SharpZipLib.

Leider muss ich feststellen, dass jedesmal die anderen Dateien/Ordner nach dem Hinzufügen einer weiteren Datei verschwunden sind. Anbei der Testcode. Anscheinend wird jedesmal die gesamte Zipdatei überschrieben, wenn ich

FileStream fso = File.OpenWrite(ZipDateipfad);

ausführe.


private void button1_Click(object sender, EventArgs e)
{
            SetText("textziptest.zip", "a.txt", "Test A");
            SetText("textziptest.zip", "b.txt", "Test B");
            SetText("textziptest.zip", "c.txt", "Test C");
}

        /// <summary>
        /// Schreibt String in eine Datei
        /// </summary>
        /// <param name="ZipDateipfad">Zipdatei</param>
        /// <param name="Dateiname">Datei in Zipdatei</param>
        /// <param name="Text">Text in Datei</param>
        public bool SetText(string ZipDateipfad, string Dateiname, string Text)
        {
            Dateiname = ZipEntry.CleanName(Dateiname);
            bool result = false;



            //Bei Bedarf Zipdatei anlegen
            if (File.Exists(ZipDateipfad) == false)
            {
                if (!Directory.Exists(new FileInfo(ZipDateipfad).DirectoryName))
                    Directory.CreateDirectory(new FileInfo(ZipDateipfad).DirectoryName);

                ZipFile zfc = ZipFile.Create(ZipDateipfad);
                zfc.BeginUpdate();
                zfc.CommitUpdate();
                zfc.Close();                
            }



            //Alte Datei in Zipdatei löschen
            ZipFile zf = new ZipFile(ZipDateipfad);                        
            if (zf == null) return result;

            ZipEntry ze = zf.GetEntry(Dateiname);
            if (ze != null)
            {
                zf.BeginUpdate();
                zf.Delete(ze);
                zf.CommitUpdate();
            }            
            zf.Close();

            

            //String als neue Datei in Zipdatei schreiben
            FileStream fso = File.OpenWrite(ZipDateipfad);
            using (ZipOutputStream zos = new ZipOutputStream(fso))
            {
                zos.SetLevel(8);

                ze = new ZipEntry(Dateiname);
                ze.DateTime = DateTime.Now;
                ze.Size = GetStreamFromString(Text).Length;

                zos.PutNextEntry(ze);

                using (Stream si = GetStreamFromString(Text))
                {
                    StreamUtils.Copy(si, zos, new byte[4096]);
                }
                zos.CloseEntry();

                zos.IsStreamOwner = false;

                zos.Finish();
                zos.Flush();
                zos.Close();
            }
            fso.Close();



            result = true;
            return result;
        }


        public Stream GetStreamFromString(string s)
        {
            MemoryStream stream = new MemoryStream();
            StreamWriter writer = new StreamWriter(stream);
            writer.Write(s);
            writer.Flush();
            stream.Position = 0;
            return stream;
        }

Habt ihr einen Tipp wie ich das anders lösen kann. In der SharpZipLib Doku habe ich noch kein Beispiel gefunden, bei dem mehrere Dateien(Memorystreams) in einzelnen Schritten zu einer bestehenden Zipdatei hinzugefügt werden.

Ich habe auch noch keine andere C# Zip Bibliothek gefunden, bei der man Memorystreams als Datei in eine Zpdatei lesen/schreiben kann.

Grüße Cornflake

16.835 Beiträge seit 2008
vor 8 Jahren

Offizielle Doku: Updating a zip file in memory

Der Umgang von Streams in Deinem Code ist übrigens immer noch, wie im anderen Thread, ein Worst-Case-Szenario und fast reif für Coding Styles Horror.
Dass da irgendwas funktioniert, grenzt an ein Wunder oder ist einfach nur Glück.
(Sorry für die Ehrlichkeit) =)

C
Cornflake Themenstarter:in
142 Beiträge seit 2007
vor 8 Jahren

@Abt: Danke hat jetzt geklappt. Allerdings muss anscheinend mit


...
ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fs, msZip, buffer);
...

zuerst die bestehende Datei in den Speicher geladen werden, um die Änderung an die richtige Stelle zuschreiben.

Wegen meinen üblen Streams, würde ich mich über eine konstruktive Kritik in Form eines Korrekturvorschlages oder Vorgehensrichtlinie freuen.

Grüße Cornflake

16.835 Beiträge seit 2008
vor 8 Jahren

Naja.. machst doch so, wie die Beispiele auch zeigen: verwende usings() korrekt.
Man braucht zB kein Close() wenn man das using() korrekt verwendet - und viele andere Stellen werden ebenfalls um längen lesbarer und sicherer.