Datei einlesen



  • Hallo

    ich möchte folgende Datei einlesen und in einer Interbase DB abspeichern.

    Die Datei sieht z.B. so aus (Vorname Name Strasse Plz Ort Tele)

    Peter Müller Musterstrasse 75 77777Musterhausen0123456789
    Alexander Mustermann Müllerstrasse 1008 78888Musterdorf 0212345698
    ...
    Die Daten sind nicht durch den TAB, ein Leerzeichen oder sonstiges getrennt. Der Vorname hat 12 Zeichen, Name hat auch 12 Zeichen, die Strassen 21 ...

    Wie liest man die einzelnen Spalten ein?
    Wird mit getline die ganze Zeile eingelesen und dann die in einzelnen Spalten getrennt, oder werden gleich die einzelnen Spalten eingelesen?
    Wie kann ich die Länge der Spalten definieren?

    Gruß

    Alex



  • Einfach die Datei in eine TStringList einlesen, dort kannst du dann die einzelnen Strings ansprechen und in die jeweiligen Zellen der DB kopieren.

    F(riendly) G(reetings) G(od)F(ather)



  • Was das Väterchen (hoffentlich) sagen wollte: du sollst nach dem Laden in die StringList die einzelenen Zeilen z.B. mit den AnsiString-Methoden zerlegen. Da du mit festen Spaltenbreiten arbeitest sollte iegentlich nicht mehr als SubString() benötigt werden.



  • Was hälst du davon ?? @Jansen

    Nutze diese Funktion immer um auch Dateien mit Spalten und Tabs als Trennzeichen erstmal in eine StringList zu schreiben. Und danach dann einfach die einzelnen Strings ansprechen und in die Zellen kopieren.
    Hab ich auch so gemacht.

    for (i = 0; i < acount; i++)  // Zeilen der Alarme
      {
        konvert=StrToInt(Form1->"StringList"->Strings[i]);
        Form1->StringGrid1->Cells[0][i]=konvert;
      }
    

    Diese Funktion spepariert die einzelnen Worte. Einfach als Delimiter (Trennzeichen) Komma oder Tab oder ähnliches eintragen.

    int SeparateWords(AnsiString Source,
    			const char Delimiter, TStringList* WordList)
    {
    	int pos = 1, start, count=0;
      AnsiString Back;
      // Alle führenden Leerzeichen entfernen
    	Source=Source.TrimLeft();
      // Auf alle Fälle erstmal die Wortliste von Altlasten befreien
      WordList->Clear();
      //
      while(pos <=Source.Length())
      {	// Suche erstes Zeichen ungleich Delimiter
        while(pos <= Source.Length() && Source[pos] == Delimiter)
        	pos++;
        //
        if(pos > Source.Length())
        	return -1;
        //
        start=pos;
        //Suche nächstes Trennzeichen oder das Zeilenende
        while(pos <= Source.Length() && Source[pos] != Delimiter)
        	pos++;
    
    		// Füge den Text in die Wortliste ein
        Back=Source.SubString(start,pos-start);
        // nochmal alle führenden und nachfolgenden Leerzeichen entfernen
        Back=Back.Trim();
        WordList->Add(Back);
        count++;
      }
      // und zurück
      return count;
    

    Ist ja eigentlich nicht das was du brauchst, aber wenn du mal eine Datei einlesen willst die aus SPalten besteht oder durch Komma getrennt ist wirds mit der Funktion leichter.



  • Das angegebene Format ohne irgendein Trennzeichen, ist zwar etwas ungewöhnlich aber nun ja. Mein Vorschlag wäre:
    Nehme einen
    TMemoryStream und davon die Methoden:

    LoadFromFile
    Seek
    ReadBuffer

    Gruß
    Gerhard



  • Wozu in den Speicher laden? TFileStream sollte es genauso tun.



  • Hallo Jansen,

    ReadBuffer soll dazu dienen, die einzelnen Elemente aus dem Stream herauszutrennen.

    Gruß
    Gerhard



  • TFileStream verfügt über dieselbe Methode, man muss also nicht erst die ganze Datei in den Speicher laden.

    Bei wirklich grossen Dateien, wo sich das wiederholt unterbrochene Lesen von der Festplatte als Flaschenhals erweisen könnte spricht der Speicherverbrauch gegen das Laden in den Speicher. Und bei kleinen Dateien, die kaum Speicher belegen, da lohnt es sich nicht, weil die Performanceeinbussen durch den Festplattenzugriff minimal bzw. nicht vorhanden sind (Caching). TMemoryStream macht nur dann Sinn, wenn die Datei über längere Zeit bzw. mehrmals hintereinander manipuliert werden soll, nicht aber beim simplen Auslesen, wie es für das Übertragen in eine Datenbank erforderlich ist.

    Bei der StringList gilt prinzipiell dasselbe wie für den MemoryStream, erstere bietet durch die Möglichkeit des unmittelbaren Einsatzes der AnsiString-Methoden aber einen echten Mehrwert.



  • Hallo Jansen,

    stimme Dir zwar im wesentlichen zu glaube aber nicht, das die eine oder andere Methode Performancevorteile hat. TFileStram ist genaus wie TMemorystream von TSream abgeleitet (Deshalb auch die gleiche Methode WriteBuffer(...)).
    Sicherlich bietet TFileStream mehr Möglichkeiten einen File zu öffnen (alleine schon durch die verschiedenen Share Modes) und ist wie schon Eingangs erwähnt für diese Aufgabe eventuell ja auch die bessere Wahl. Ich benutze sehr oft TMemorystream (jeder hat ja seine eigen Macke) und dann sieht man den Wald vor lauter Bäumen nicht mehr.

    Gruß
    Gerhard



  • Gerhard schrieb:

    glaube aber nicht, das die eine oder andere Methode Performancevorteile hat

    Es sollte, eine gewisse Dateigrösse vorausgesetzt, eindeutig "performanter" sein, die Datei in einem Rutsch in den Speicher zu lesen und dort dann stückweise auszulesen (TMemoryStream) als den LeseKopf der Festplatte ständig anzuhalten und neu zu starten, wenn man die Daten stückweise von der Festplatte liest. Speicherzugriffe sind nun mal um vieles schneller als Festplattenzugriffe. Das ist aber nur theoretisch beachtenswert, Begründung siehe oben.

    wie schon Eingangs erwähnt

    Wo denn?


Anmelden zum Antworten