Kleines Freizeitprojekt gesucht

Hier kann alles mögliche diskutiert werden. Themen zu Purebasic sind hier erwünscht.
Flames und Spam kommen ungefragt in den Mülleimer.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Kleines Freizeitprojekt gesucht

Beitrag von Kiffi »

@LJ: Du liest die komplette CSV in den Speicher und parst sie dann?
Little John hat geschrieben:Hast Du da 'ne gute Idee, Kiffi?
SQLite mit einer :memory: - Datenbank :-)

Grüße ... Kiffi
a²+b²=mc²
Little John

Re: Kleines Freizeitprojekt gesucht

Beitrag von Little John »

Kiffi hat geschrieben:@LJ: Du liest die komplette CSV in den Speicher und parst sie dann?
Nein im Moment nicht. Zur Zeit besteht der Code aus den 2 Routinen:

Code: Alles auswählen

ReadCsvRecord()
WriteCsvRecord()
Es wird immer der nächste Datensatz vom Datenträger gelesen bzw. darauf geschrieben. Aber das lässt sich bei Bedarf ja leicht ändern.
Kiffi hat geschrieben:
Little John hat geschrieben:Hast Du da 'ne gute Idee, Kiffi?
SQLite mit einer :memory: - Datenbank :-)
Theoretisch habe ich daran auch schon gedacht. Praktisch habe ich davon keine Ahnung. :mrgreen:

Z.Z. wird jeder Record in einer Datenstruktur gehalten, die es in PB nicht gibt. Das Ähnlichste in PB wäre eine verkettete Liste. Aber auch das lässt sich leicht ändern. In welcher Form sollte denn ein Datensatz am besten an die SQLite-Datenbank übergeben werden?

Ich glaube, dass meine Routinen "ziemlich kugelsicher" sind:
Ich habe verschiedene Literaturquellen berücksichtigt, und Tests z.B. mit Excel und OpenOffice gemacht. Innerhalb eines Feldes das von Quotes begrenzt ist können natürlich Feldtrennzeichen vorkommen, ebenso wie Quotes und Zeilenumbrüche. Ich würde die Routinen dann konvertieren, anpassen und zwecks Überprüfung "zum Beschuss" freigeben. :D
Die Routinen werden aber sicher nicht von Anfang an auf Geschwindigkeit hin optimiert sein. Dazu fehlt in PureBasic der Time-Profiler bzw. mir die Erfahrung, was in PureBasic wie schnell geht.

Gruß, Little John
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Kleines Freizeitprojekt gesucht

Beitrag von Kiffi »

Little John hat geschrieben:Nein im Moment nicht.
Gut! :allright:

Spaß beiseite: Theoretisch können CSV-Dateien unbegrenzt
groß sein. Ich muss beispielsweise CSV-Dateien parsen, die
schon mal 500 MB groß sind. Diese komplett in den Speicher
laden zu wollen ist natürlich suboptimal.

Ich verwende übrigens für obige Dateien die DotNet
TextFieldParser-Klasse.

In PB habe ich testweise ODBC verwendet, was aber aufgrund
der zu generierenden Schema.ini ein ziemliches Gehampel ist.
Little John hat geschrieben:Z.Z. wird jeder Record in einer Datenstruktur gehalten, die es in PB nicht gibt.
welche Sprache verwendest Du hier?
Little John hat geschrieben:In welcher Form sollte denn ein Datensatz am besten an die SQLite-Datenbank übergeben werden?
Schwierig...

Normalerweise liest man die erste Zeile ein, parst sie und kennt
dann die Anzahl der Felder. Aufgrund dieser Information kann man
dann die Tabelle erstellen:

Code: Alles auswählen

Create Table CSV (c1, c2, c3, ...)
danach wird Zeile für Zeile geparst und in die Tabelle eingefügt:

Code: Alles auswählen

Insert Into CSV (c1, c2, c3, ...) Values ('" + v1 + "', '" + v2 + "', '" + v3 + "'...)
soweit die Theorie...

Was aber, wenn eine Zeile mehr Felder als die anderen Zeilen enthält?

Code: Alles auswählen

v1;v2;v3
v1;v2;v3
v1;v2;v3;v4
v1;v2;v3
(ist meines Erachtens CSV-technisch erlaubt)

Also müsste man die CSV zweimal parsen: Ein Lauf, um die max. Anzahl
der Felder zu ermitteln (und dann die Tabelle zu erstellen)
und einmal, um die Daten zu ermitteln. Das macht die Sache natürlich nicht
schneller...

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
zoidberg
Beiträge: 219
Registriert: 06.12.2004 23:15
Computerausstattung: Acer 6530
Mit Ubuntu 9.04 64 Bit als Hauptsystem und
Windows Vista 32Bit Home Premium zum spielen.
Wohnort: GM
Kontaktdaten:

Re: Kleines Freizeitprojekt gesucht

Beitrag von zoidberg »

Also, daß eine Zeile mehr Werte enthält geht. Ich habe es gerade ausprobiert.
Bild
Little John

Re: Kleines Freizeitprojekt gesucht

Beitrag von Little John »

Kiffi hat geschrieben:Theoretisch können CSV-Dateien unbegrenzt
groß sein. Ich muss beispielsweise CSV-Dateien parsen, die
schon mal 500 MB groß sind. Diese komplett in den Speicher
laden zu wollen ist natürlich suboptimal.
Ja, genau deshalb verarbeite ich Dateien immmer gerne in kleineren "Häppchen" (wenn möglich).
Kiffi hat geschrieben:Ich verwende übrigens für obige Dateien die DotNet
TextFieldParser-Klasse.
Ich weiß mal grade so was "DotNet" bedeutet, aber mehr nicht. :D
Kiffi hat geschrieben:welche Sprache verwendest Du hier?
Siehe Posteingang. :-)
Kiffi hat geschrieben:
Little John hat geschrieben:In welcher Form sollte denn ein Datensatz am besten an die SQLite-Datenbank übergeben werden?
Schwierig...

Normalerweise liest man die erste Zeile ein, parst sie und kennt
dann die Anzahl der Felder. Aufgrund dieser Information kann man
dann die Tabelle erstellen:

Code: Alles auswählen

Create Table CSV (c1, c2, c3, ...)
danach wird Zeile für Zeile geparst und in die Tabelle eingefügt:

Code: Alles auswählen

Insert Into CSV (c1, c2, c3, ...) Values ('" + v1 + "', '" + v2 + "', '" + v3 + "'...)
soweit die Theorie...
Vielen Dank, da hast Du mir erstmal die richtige Richtung gezeigt. Ich werde mich sobald wie möglich dazu belesen.
Kiffi hat geschrieben:Was aber, wenn eine Zeile mehr Felder als die anderen Zeilen enthält?

Code: Alles auswählen

v1;v2;v3
v1;v2;v3
v1;v2;v3;v4
v1;v2;v3
(ist meines Erachtens CSV-technisch erlaubt)
Ja? Ich dachte immer das sei nicht erlaubt. Aber Du kennst Dich da bestimmt besser aus. Ich dachte, dass die "kürzeren" Records dann mit leeren Feldern aufgefüllt werden müssen:

Code: Alles auswählen

v1;v2;v3;
v1;v2;v3;
v1;v2;v3;v4
v1;v2;v3;
Kiffi hat geschrieben:Also müsste man die CSV zweimal parsen: Ein Lauf, um die max. Anzahl
der Felder zu ermitteln (und dann die Tabelle zu erstellen)
und einmal, um die Daten zu ermitteln. Das macht die Sache natürlich nicht
schneller...
Nee, nicht schön das ...

Spontan fällt mir dazu folgendes ein:
1. Datensatz lesen, wenn dieser 10 Felder enthält, dann z.B. eine Tabelle mit 20 Feldern erzeugen -- in der Annahme, dass das höchstwahrscheinlich für alle Datensätze in dieser Datei ausreichen wird. Und falls das im Ausnahmefall mal nicht ausreicht, muss eben doch 2x gelesen werden ... aber diese Fälle werden dann wohl ziemlich selten sein. Kann man denn eine SQLite-Tabelle mit 20 Feldern schnell auf 10 Felder "kürzen", falls man am Ende der Datei feststellt dass alle Records doch nur 10 Felder hatten?

Oder die CSV-Daten evtl. in PureBasics XML-Datenstrukturen einlesen? Ist auf jeden Fall flexibler, und man muss die maximale Feldanzahl nicht vorher kennen.
zoidberg hat geschrieben:Also, daß eine Zeile mehr Werte enthält geht. Ich habe es gerade ausprobiert.
Was genau? Mit welchem Programm?

Gruß, Little John
Benutzeravatar
rolaf
Beiträge: 3843
Registriert: 10.03.2005 14:01

Re: Kleines Freizeitprojekt gesucht

Beitrag von rolaf »

Little John hat geschrieben:Ja? Ich dachte immer das sei nicht erlaubt. Aber Du kennst Dich da bestimmt besser aus. Ich dachte, dass die "kürzeren" Records dann mit leeren Feldern aufgefüllt werden müssen:

Code: Alles auswählen

v1;v2;v3;
v1;v2;v3;
v1;v2;v3;v4
v1;v2;v3;
Gibts bei CSV überhaupt festgelegte Regularien?
Ich würde ner CSV immer einen "Header" verpassen, dann ist es eindeutig welche Felder es gibt.

Code: Alles auswählen

Name;Strasse;Postleitzahl;Ort
v1;v2;v3;
v1;v2;v3;
v1;v2;v3;v4
v1;v2;v3;
v1;v2;;v4
Das mit den leeren Feldern (wie Little John meint) könnte stimmen, da ja auch zwischen einen Datensatz Daten fehlen können die durch ein leeres Feld eingetragen sein müßen (siehe die letzte Zeile im Code oben).
:::: WIN 10 :: PB 5.73 :: (x64) ::::
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Kleines Freizeitprojekt gesucht

Beitrag von Kiffi »

Little John hat geschrieben:Ich weiß mal grade so was "DotNet" bedeutet, aber mehr nicht. :D
Schäm Dich! :-)
Little John hat geschrieben:Kann man denn eine SQLite-Tabelle mit 20 Feldern schnell auf 10 Felder "kürzen", falls man am Ende der Datei feststellt dass alle Records doch nur 10 Felder hatten?
ja, kann man. Allerdings funktioniert das bei SQLite ein wenig umständlicher als bei anderen DBs. Hier gibt es nämlich kein
Alter Table, sondern man muss eine neue Tabelle erstellen und diese mit dem Inhalt der alten Tabelle befüllen (Insert Into
NeueTabelle Select * From AlteTabelle
)
Little John hat geschrieben:Oder die CSV-Daten evtl. in PureBasics XML-Datenstrukturen einlesen? Ist auf jeden Fall flexibler, und man muss die maximale Feldanzahl nicht vorher kennen.
ist mir gestern unter der Dusche auch eingefallen. :lol:
Müsste man im Einzelfall mal schauen, wie gut die Performance ist.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Kleines Freizeitprojekt gesucht

Beitrag von ts-soft »

DrFalo hat geschrieben: Gibts bei CSV überhaupt festgelegte Regularien?
Gibts nicht! (lediglich MS-bildet sich wieder ein, so wie sie es machen ist es standard :mrgreen: )
http://de.wikipedia.org/wiki/CSV_%28Dateiformat%29

So kann man beim Import einer CSV-Datei in Calc auch definieren, wie es zu importieren ist,
wohingegen Excel da oft Müll importiert :mrgreen:

Gruß
Thomas
Antworten