Entwickler-Ecke
IO, XML und Registry - Problem mit StreamWriter und Erzeugung einer CSV-Datei
DonC - Mo 03.11.08 13:11
Titel: Problem mit StreamWriter und Erzeugung einer CSV-Datei
Hi,
mit folgendem Code erzeuge ich in meinem Programm eine CSV-Datei:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| private bool exportCSV(string filepath, char separator, ArrayList csv_data) { bool retVal = true;
try { FileStream outStream = new FileStream(filepath, FileMode.OpenOrCreate); StreamWriter sw = new StreamWriter(outStream, System.Text.Encoding.Default); string csv_line;
foreach (string[] product in csv_data) { csv_line = ""; foreach (string value in product) { csv_line = csv_line + value + separator; } sw.WriteLine(csv_line); } sw.Close(); } catch (Exception e) { retVal = false; }
return retVal; } |
Soweit, so gut. Die Ausgabe ist eine CSV-Datei, in welcher die einzelnen Werte durch Semikolons getrennt sind. Wenn ich diese Datei nun jedoch in Excel öffne, interpretiert er die Semikolons nicht richtig, d.h. er bringt die Spaltenreihenfolge durcheinander, vermischt die erste mit der vierten Spalte und verteilt den Text der vierten Spalte über mehrere Zeilen, obwohl keinerlei Zeilenumbrüche im Text definiert sind. Meine Vermutung ist, dass irgendetwas mit der Zeichenformatierung nicht stimmt, nur was könnte das sein? Wäre super nett, wenn Ihr mir helfen könntet.
Kha - Mo 03.11.08 13:39
Ich denke nicht, dass ihm das abschließende Semikolon gefallen wird, benutze lieber String.Join. Ansonsten lässt sich von hier aus wenig sagen, eine Beispieldatei wäre schön.
DonC - Mo 03.11.08 13:56
Hi,
ich weiss jetzt glaube ich wo der Hund begraben ist. An dem abschliessenden Semikolon liegt es nicht. In der dritten Spalte enthält der Eingabestring mehrere EOL-Zeichen (End of Line), welche gleichzeitig für einen Zeilenumbruch sorgen. Die Sache ist nämlich, dass der String HTML-Code enthält. Die Lösung meines Problems liegt wohl darin, die EOL-Zeichen aus dem String zu entfernen. Durch ein einfaches Entfernen von Zeilenumbrüchen mit Replace("\n", "") geht das leider nicht. Nur habe ich keine Ahnung, wie man aus einem String die EOL-Zeichen entfernen kann. Vielleicht weiss ja jemand von Euch wie das geht.
JüTho - Mo 03.11.08 14:23
Dann musst Du Dir die Ausgangsdatei in einem Hex-Editor ansehen und prüfen, wie genau das EOL gespeichert ist. "Ausprobieren" für Replace geht noch mit '\r' und '\n' und Environment.NewLine.
Im Übrigen ist statt String.Join noch besser die Verwendung des StringBuilder mit Append. Erklärung: Beim Ändern eines Strings muss immer im Arbeitsspeicher umkopiert werden; das steuert der StringBuilder erheblich besser. Außerdem empfehle ich, statt des StreamWriter File.AppendText zu verwenden.
Noch besser wäre es, alle Zeilen zunächst im Arbeitsspeicher zusammenzustellen; das geht mit dem StringBuilder am einfachsten. Am Schluss wird alles am Stück mit File.WriteAllText gespeichert.
Jürgen
DonC - Mo 03.11.08 14:59
JüTho hat folgendes geschrieben : |
Dann musst Du Dir die Ausgangsdatei in einem Hex-Editor ansehen und prüfen, wie genau das EOL gespeichert ist. "Ausprobieren" für Replace geht noch mit '\r' und '\n' und Environment.NewLine.
Im Übrigen ist statt String.Join noch besser die Verwendung des StringBuilder mit Append. Erklärung: Beim Ändern eines Strings muss immer im Arbeitsspeicher umkopiert werden; das steuert der StringBuilder erheblich besser. Außerdem empfehle ich, statt des StreamWriter File.AppendText zu verwenden.
Noch besser wäre es, alle Zeilen zunächst im Arbeitsspeicher zusammenzustellen; das geht mit dem StringBuilder am einfachsten. Am Schluss wird alles am Stück mit File.WriteAllText gespeichert.
Jürgen |
Mit Replace "\r" hat' geklappt. Nun wird die CSV auch korrekt von Excel eingelesen. Besten Dank nochmal :)
Werde den Code auch nochmal nach Deinen Empfehlungen anpassen. Macht auf jeden Fall Sinn.
Kha - Mo 03.11.08 17:08
JüTho hat folgendes geschrieben : |
| Im Übrigen ist statt String.Join noch besser die Verwendung des StringBuilder mit Append. |
Das finde ich hier unangemessen. Der Flaschenhals ist eindeutig die Festplatte, es spricht nichts dagegen, durch string.Join ein paar Zeilen Code einzusparen. Und wenn er wie bisher zeilenweise schreibt, hat er sogar weniger Speicherverbrauch als mit einem großen StringBuilder.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!