Abholen müssen, Zeilenende-Zeichen mit StreamReader.ReadLine()
Schrieb ich ein C# - Programm zum Lesen von Excel .xls/.xlsx Datei und Ausgabe in CSV-und Unicode-text. Ich schrieb ein separates Programm zum entfernen von leeren Datensätzen. Dies geschieht durch Lesen jede Zeile mit StreamReader.ReadLine()
, und dann geht Zeichen für Zeichen durch den string und nicht schreibt in die Zeile ausgeben, wenn es enthält alle Kommas (für CSV) oder alle tabs (für die Unicode-text).
Das problem tritt auf, wenn die Excel-Datei enthält eingebettete Zeilenumbrüche (\x0A) innerhalb der Zellen. Ich habe meinen XLS zu CSV converter zu finden, diese neuen Zeilen (da geht es Zelle für Zelle) und schreiben Sie als \x0A und normalen Linien verwenden Sie einfach StreamWriter.WriteLine().
Tritt das problem auf, in das separate Programm zu entfernen, leere Datensätze. Wenn ich lese, mit StreamReader.ReadLine()
, es per definition nur gibt den string zurück, mit der Linie, nicht der terminator. Da der eingebettete Zeilenumbrüche anzeigen als zwei separate Zeilen, ich kann nicht sagen, das ist eine vollständige Aufzeichnung und das ist ein embedded-newline für die, wenn ich Sie Schreibe, um die endgültige Datei.
Ich bin mir auch nicht sicher, ich kann Lesen in der \x0A, weil alles, was auf der input-Register, '\n'. Ich könnte gehen, Zeichen für Zeichen, aber das zerstört meine Logik, um leere Zeilen entfernen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich würde empfehlen, dass Sie Ihre Architektur zu arbeiten, die mehr wie ein parser in einem compiler.
Den Sie erstellen möchten, ein lexer, gibt eine Sequenz von Token und dann ein parser liest die Abfolge der Token und macht Sachen mit Ihnen.
In Ihrem Fall die Token wäre:
Würden Sie behandeln '\n' ('\x0a') von selbst als eine eingebettete neue-Zeile -, und daher als Teil einer Spalte Daten-token. Ein '\r\n' wäre eine End-of-Line-token.
Dies hat die Vorteile:
Hier ist ein Beispiel, was der Lexer würde wie folgt Aussehen:
Haftungsausschluss: ich habe nicht selbst kompiliert, geschweige denn getestet, dieser code, so dass Sie brauchen werden, um es zu säubern und sicherzustellen, dass es funktioniert.
Ihre "parser" code würde dann wie folgt Aussehen:
Können Sie nicht ändern
StreamReader
zurück die Zeilenende-Zeichen und Sie können nicht ändern, was nutzt es nach Beendigung der Zeile.Ich bin mir nicht ganz im klaren über das problem in Bezug auf das, was entkommen Sie tun, besonders in Bezug auf "schreiben als " \x0A". Ein Beispiel der Datei würde wahrscheinlich helfen.
Es klingt wie Sie kann arbeiten müssen, Zeichen für Zeichen, oder vielleicht laden Sie die gesamte Datei zuerst und machen Sie einen globalen ersetzen, z.B.
Ich bin mir sicher, dass Sie tun könnte, dass mit einer regex und es wäre wahrscheinlich effizienter, aber ich finde der lange Weg leichter zu verstehen 🙂 Es ist ein bisschen ein hack zu tun eine Globale ersetzen, wenn - hoffentlich mit mehr Informationen, wir werden kommen mit eine bessere Lösung.
Im wesentlichen, einen hard-return in Excel (shift+enter oder alt+enter, ich kann mich nicht erinnern) setzt einen Zeilenumbruch, das ist äquivalent zu \x0A in der Standard-Codierung verwende ich das schreiben meiner CSV. Wenn ich Schreibe das CSV-Format, ich benutze StreamWriter.WriteLine(), die Ausgänge der Linie plus ein newline (was ich glaube, ist \r\n).
Die CSV ist gut und kommt genau wie Excel speichern, das problem ist, wenn ich Lesen Sie es in den leeren Datensatz Entferner, bin ich mit ReadLine (), die zu behandeln, wird ein Datensatz mit einem eingebetteten newline als ein CRLF.
Hier ist ein Beispiel für die Datei nach dem konvertieren der CSV...
Wie Sie sehen können, der erste Datensatz hat eine eingebettete neue-Zeile nach al-Numan. Wenn ich mit ReadLine(), bekomme ich die Meldung '1050,"Aziz Salih al-Numan' und wenn ich Schreibe, dass aus, WriteLine() endet diese Zeile mit einem CRLF. Ich verliere das original-line terminator. Wenn ich mit ReadLine() erneut, bekomme ich die Zeile beginnend mit '1050a'.
Konnte ich die gesamte Datei zu Lesen und diese zu ersetzen, aber dann müsste ich ersetzen, Sie wieder hinterher. Im Grunde, was ich tun möchten ist, bekommen die line terminator zu bestimmen, ob seine \x0a oder ein CRLF, und dann, wenn seine \x0A, werde ich verwenden, Write() und insert, der terminator.
Ich weiß, ich bin ein wenig spät, um das Spiel hier, aber ich hatte das gleiche problem und meine Lösung war viel einfacher, als die meisten gegeben.
Wenn Sie sind in der Lage, um zu bestimmen, die Anzahl der Spalten, die einfach sein sollte zu tun, da die erste Zeile ist in der Regel die Spaltenüberschriften, können Sie überprüfen Sie Ihre Spalte zählen, gegen die zu erwartende Anzahl der Spalten. Wenn die Anzahl der Spalten entspricht nicht der erwarteten Anzahl der Spalten, die Sie einfach verketten Sie die aktuelle Zeile mit der vorherigen unvergleichlichen Linien. Zum Beispiel:
Danke, dass Sie so viel mit Ihrem code und einige andere, kam ich mit der folgenden Lösung! Ich habe einen link unten, um einige code, den ich schrieb, dass die Logik von dieser Seite. Ich dachte, ich würde geben, Ehren, denen Ehre war fällig! Danke!
Unten ist eine Erklärung über das, was ich gebraucht habe:
Versuchen Sie Dieses, ich schrieb dies, weil ich einige sehr große '|' Trennzeichen getrennte Dateien, die \r\n im inneren von einigen der Spalten und ich brauchte, um \r\n als Zeilenende-Trennzeichen. Ich war versucht, zu importieren einige Dateien mit Hilfe von SSIS-Pakete, aber aufgrund von fehlerhaften Daten in den Dateien, die ich nicht in der Lage war zu. Die Datei war über 5 GB, so war es zu groß, zu öffnen und manuell zu beheben. Ich fand die Antwort durch die Suche durch viele Foren, um zu verstehen, wie die streams funktionieren und endete kommen mit einer Lösung, die liest jedes Zeichen in einer Datei und spuckt die Linie basiert auf den Definitionen, die ich Hinzugefügt. dies ist für die Verwendung in einer Kommandozeilen-Anwendung, komplett mit helfen :). Ich hoffe das hilft einigen anderen Menschen aus, habe ich noch keine Lösung gefunden, ganz wie es anderswo, obwohl die Ideen waren inspiriert durch dieses forum und andere.
https://stackoverflow.com/a/12640862/1582188