| |
|
|
Christof Neuß | Hallo,
immer wenn Du denkst es geht jetzt wieder, kommt von irgendwo ein Stoppschild her...
Wenn ich meine CSV-Datei mit einem Hex-Editor öffne, sieht das am Anfang so aus wie in der angehängten Datei zu ersehen ist.
Diese CSV-Dateien kommen von einem Großrechner aus dem Rechenzentrum und sind wohl mit einem anderen Zeichensatz codiert. Excel, Windows-Editor und andere Programme machen eigentlich keine Schwierigkeiten. Evtl. muss ich die ersten beiden Zeichen löschen, aber sonst klappt das.
Ich möchte diese Dateien - die durchaus mal 150 MB groß werden können - in einen Speicherbereich und dann in ein/mehrere Arrays laden, um diese dann weiterverarbeiten zu können. Der "normale", zeilenweise Weg über "Input #2, DateiInhalt$" funktioniert, ist aber sehr langsam. Daher der Versuch, die Datei mit "Blockread" schnell in einen Bereich zu holen.
Es gibt keine Fehlermeldung, aber beim ersten 00-Byte, also nach dem "P" hört Blockread auf.
Was kann ich tun oder welche andere elegante Lösung gibt es, eine CSV-Datei ruckzuck zu importieren?
Vielen Dank und viele Grüße
Christof |
|
|
| |
|
|
|
Michael W. | FF FE ist der BOM für UTF-16-LE.
Windows Unicode ist UTF-16 (LE)
WideString (v X3) kann den BOM erkennen und automatisch entfernen.
BlockRead muß dann mit der alten Syntax mit Offset und Anzahl genutzt werden. Dann werden die Daten einfach als Datenblock betrachtet und können einfach eingelesen werden. Mit WideString und natürlich auch mit "Declare wide stringvar" kann dann ganz normal aus dem Bereich in Variablen getextet werden. |
|
|
| |
|
|
|
Christof Neuß | Also, das funktioniert jetzt schon mal einigermaßen gut. Aber ich bin noch nicht am Ziel...
Var Datei$="C:\_SEntw\_XProfanX3_1\_TestDB_mit_CSV\GGBIDA_KDU.CSV"
Var DateiLaenge&=FileSize(Datei$)
MessageBox(Str$(DateiLaenge&),"Meldung",0)'112436764
Var DateiGelesen&=0
Var Ergebnis$=""
Declare Bereich#
Dim Bereich#, DateiLaenge&
Assign #1, Datei$
OpenRW #1
DateiGelesen&=BlockRead(#1, Bereich#, 0, DateiLaenge& )
Close #1
MessageBox("Fertig mit Einlesen","Meldung",0)
'Ergebnis$=WideString(Bereich#, 0) '--> dauert ewig
'Ergebnis$=WideChar(Bereich#, 0, DateiLaenge&) '--> Fehlermeldung Zugriffsverletzung!
'Funktioniert so bis ca. 56.700.000
Ergebnis$=WideChar(Bereich#, DateiLaenge&-100,100)'--> Funktioniert! STRING ist also vollständig da.
MessageBox(left$(Ergebnis$,300),"Meldung",0)'nur, um zu sehen, ob auch was angekommen ist
Die Datei ist also über 100 MB groß, die ich einlesen möchte. Einlesen funktioniert auch. Und das richtig schnell. Der anschließende Übertrag in eine normale String-Variable hakt allerdings noch etwas.
Hab's erst mit WideString() probiert. Das Programm ist weder im Interpreter noch als EXE zum Ende gekommen. Musste ich immer abbrechen.
Mit WideChar() geht es irgendwie nur bis knapp 57 Mio. Zeichen. Darüber kommt eine Fehlermeldung.
Habe dann mal das "Ende" der Bereichsvariablen überprüft. Klappt. Es sind also alle Daten im Speicher.
Jemand noch eine Idee dazu?
Wiederum "Danke und Gruß"
Christof |
|
|
| |
|
|
|
H.Brill | Die interne Listboxliste dürfte evtl. zu klein sein. Immerhin laut Hilfe :
Ab Version 11 kann sie bis zu 260.000 Strings aufnehmen und verwalten
Da du Version X3 zu haben scheinst, könnte man noch den Versuch mit
Move("FileToList", Dateiname$)
probieren.
In diesem Zusammenhang wäre es interessant, wenn die beiden Move-Funktionen (FileToList und ListToFile) auch die Codierungen als optionalen Parameter berücksichten könnten. Man hat ja des Öfteren anders (UTF-8, UTF-16 usw.) codierte Textdateien. Dann könnte man sich die separate Umwandlung sparen.
Wäre ein Wunsch zum nächsten Update. |
|
|
| Benutze XPROFAN X3 + FREEPROFAN Wir sind die XProfaner. Sie werden von uns assimiliert. Widerstand ist zwecklos! Wir werden alle ihre Funktionen und Algorithmen den unseren hinzufügen.
Was die Borg können, können wir schon lange. | 06.11.2016 ▲ |
|
|
|
|
Michael W. | Ich weiß ja nicht was da genau dann mit den Daten passieren soll. Also einfach mal 2 Überlegungen:
1. Blockweise Einlesen. Schau Dir einfach mal an, wie das Zeilenende codiert ist. Dann einen großen Block einlesen und zurück bis zu einem Zeilenende. Also Anzahl der gelesenen Zeichen reduzieren. Das ganze bearbeiten und wieder wegschreiben. Danach an der neuen (evtl. reduzierten) Stelle weiter einlesen. Bis alles durch ist.
2. Kombinieren mit Firebird oder SQLite Blockweise Einlesen und gleich in die Datenbank. Und dann erst in der Datenbank bearbeiten. Da dürfen die Daten fast beliebig groß werden.
Es muß ja nicht alles in den Hauptspeicher bis dieser platzt. Wenn dann die Bearbeitung nicht satzweise erfolgen soll, sondern bestimmte Bereiche summiert werden sollen ist eine Datenbank sowieso besser, da dann mittels Select sehr viel mehr und dann auch sehr viel schneller erledigt werden kann.
Übrigens dachte ich an eine ECHTE Csv-Datei. Diese besteht aus mehreren Sätzen (Zeilentrenner unbekannt, da Ausschnitt zu klein) und innerhalb der Sätze aus mehreren Feldern (die mit TAB \t getrennt sind). |
|
|
| System: Windows 8/10, XProfan X4 Programmieren, das spannendste Detektivspiel der Welt. | 07.11.2016 ▲ |
|
|
|
|
Christof Neuß | Hallo Michael,
vielen Dank für die Hinweise, die mir schon gut weitergeholfen haben. Auch wenn ich jetzt wieder längere Zeit mit anderen Dingen beschäftigt war, ist das Thema noch aktuell für mich.
Aufgrund der einfachen Einbindung von Firebird, werde ich damit arbeiten. Ziel/Aufgabe ist es, mehrere (relativ große) CSV-Dateien (Tab getrennt, UTF-16) möglichst schnell in die Datenbank zu übertragen.
Vielleicht hast Du noch ein paar Tipps für mich (natürlich darf sich auch jeder andere gerne melden), wie ich das am besten hinbekomme?!
Vielen Dank und Gruß
Christof |
|
|
| |
|
|