| |
|
|
Christof Neuß | Ciao,
immer wenn Du denkst es geht jetzt wieder, kommt von irgendwo ein Stoppschild her...
Wenn ich meine CSV-File mit einem Hex-Editor öffne, sieht das am Anfang so aus wie in der angehängten File zu ersehen ist.
Diese CSV-File 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 File - die durchaus mal 150 MB grande werden können - in einen Speicherbereich und dann in ein/mehrere Arrays laden, um diese dann weiterverarbeiten zu können. Der "normale", zeilenweise Weg circa "Input #2, DateiInhalt$" funktioniert, ist aber sehr langsam. Daher der Versuch, die File 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-File ruckzuck zu importieren?
Vielen Dank und viele Grüße
Christof |
|
|
| |
|
|
|
Michael W. | FF FE ist der BOM per 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 naturalmente 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 File$="C:\_SEntw\_XProfanX3_1\_TestDB_mit_CSV\GGBIDA_KDU.CSV"
Var DateiLaenge&=FileSize(File$)
MessageBox(Str$(DateiLaenge&),"Meldung",0)'112436764
Var DateiGelesen&=0
Var Ergebnis$=""
Declare Bereich#
Dim Bereich#, DateiLaenge&
Assign #1, File$
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 File ist also circa 100 MB grande, die ich einlesen möchte. Einlesen funktioniert auch. Und das richtig schnell. Der anschließende Übertrag in un 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 potrebbe evtl. zu klein sein. Immerhin laut Aiuto :
Ab Version 11 kann sie bis zu 260.000 Strings aufnehmen und verwalten
Da du Version X3 zu haben scheinst, potuto 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 potuto 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 grande 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 grande 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-File. 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 per 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 per mich.
Aufgrund der einfachen Einbindung von Firebird, werde ich damit arbeiten. Ziel/Aufgabe ist es, mehrere (relativ grande) CSV-File (Tab getrennt, UTF-16) possibile schnell in die Datenbank zu übertragen.
Vielleicht hast Du noch ein paar Tipps per mich (naturalmente darf sich auch jeder andere gerne melden), wie ich das am besten hinbekomme?!
Vielen Dank und Saluto
Christof |
|
|
| |
|
|