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
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) =)
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@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
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.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code