Pit Stop: Dos-Formatierten Text einlesen

Hi zusammen,

ich möchte diverse Textdateien in einen datenbank einlesen.
Alles soweit eiinfach und kein Problem...

Die Dateien sind allerding snoch in DOS erstellt und beinhalten daher viel "datenmüll" wie z.B. "ÿÿÿÿÿÿÿÿÿÿÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ" und zeichen die sich hier nicht darstelln lassen.
Gibts in Php einen befehl, der ähnlich wie mb_convert_string_encoding diese zeichen ignoriert und streicht?
Über Stringverarbeitung (str_replace/preg_replace oder ähnliches) funktioniert das nicht.

Vielen Dank!

Pit

  1. Die Dateien sind allerding snoch in DOS erstellt und beinhalten daher viel "datenmüll" wie z.B. "ÿÿÿÿÿÿÿÿÿÿÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ" und zeichen die sich hier nicht darstelln lassen.

    Kannst Du "datenmüll" so beschreiben, wie man es einem Computer mitteilen müßte? Der weiß nämlich nicht wie Zeichen aussehen und was gewollt ist. Kannst Du sagen welche Zeichen alle raus sollen oder welche Zeichen alle drin bleiben sollen?

    Über Stringverarbeitung (str_replace/preg_replace oder ähnliches) funktioniert das nicht.

    Was hast du denn probiert?

  2. echo $begrüßung;

    Die Dateien sind allerding snoch in DOS erstellt und beinhalten daher viel "datenmüll" wie z.B. "ÿÿÿÿÿÿÿÿÿÿÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ" und zeichen die sich hier nicht darstelln lassen.

    Finde heraus, in welcher Kodierung (nicht Format!) die Texte sind. Schau dir den Text in einem Hexeditor an und suche zu den "Müll"-Zeichen die Bytewerte und errate, welches Zeichen sie darstellen sollen. Vergleiche dann die Bytewerte mit Kodierungen wie CP437 und CP850. Das sind die wahrscheinlichsten, wenn die Texte westeuropäischen Ursprungs sind.

    Gibts in Php einen befehl, der ähnlich wie mb_convert_string_encoding diese zeichen ignoriert und streicht?

    Wenn du von ignorieren sprichst, dann könnte es auch sein, dass du keine Textdatei sondern eine strukturierte Datei vorliegen hast und zufällige Bytewerte an "ungenutzten Stellen" stehen. In dem Fall solltest du nicht mit Textdatei-Methoden hantieren sondern die Daten der Struktur entnehmen. Umkodieren wirst du sie dann möglicherweise immer noch müssen.

    Beispielsweise können Stringwerte mit vorangehendem Längenbyte gespeichert sein (Pascal-Stil) oder mit einem bestimmten Zeichen aufhören (00-Byte - C-Stil).

    Über Stringverarbeitung (str_replace/preg_replace oder ähnliches) funktioniert das nicht.

    Das funktioniert schon, nur müssen die Bytewerte der Zeichen im Quelltext mit den Bytewerten der Zeichen in der Datei übereinstimmen.

    echo "$verabschiedung $name";

    1. Hi nochmal,

      danke schon mal für den Hinweis.
      es handelt sich woh lwirklich um CP437-Kodierung.

      "Wenn du von ignorieren sprichst, dann könnte es auch sein, dass du keine Textdatei sondern eine strukturierte Datei vorliegen hast und zufällige Bytewerte an "ungenutzten Stellen" stehen. In dem Fall solltest du nicht mit Textdatei-Methoden hantieren sondern die Daten der Struktur entnehmen. Umkodieren wirst du sie dann möglicherweise immer noch müssen."

      => kannst Du mir das nochmal genauer erklären?
      Wie kann ich die Daten der Struktur entnehmen??

      Vielen Dank, pit

      1. echo $begrüßung;

        "Wenn du von ignorieren sprichst, dann könnte es auch sein, dass du keine Textdatei sondern eine strukturierte Datei vorliegen hast und zufällige Bytewerte an "ungenutzten Stellen" stehen. In dem Fall solltest du nicht mit Textdatei-Methoden hantieren sondern die Daten der Struktur entnehmen. Umkodieren wirst du sie dann möglicherweise immer noch müssen."

        => kannst Du mir das nochmal genauer erklären?
        Wie kann ich die Daten der Struktur entnehmen??

        Beispielweise könnten die Daten so aussehen:

        iiiizssssssssssiiiizssssssssssiiiizssssssssss...

        i steht für ein Byte eines Integerwertes, z ist ein Längenbyte für den Stringwert (s).

        iiii4testmüllxyiiii3fooblafasliiii8Pit Stopxy...

        Der Integerwert ist erstmal uninteressant, deswegen lass ich die Platzhalter-i dort stehen. Interessant sind die Stringwerte. Die 4 steht für den Bytewert 4 und gibt an, dass der String aus 4 Zeichen besteht. Der Rest (müllxy) ist uninteressant, das sind zufällige Werte. Das gleiche Prinzip gilt für die Strings "foo" und "Pit Stop".

        Die Struktur eines Records wurde definiert als Integer gefolgt von einem maximal 10-stelligen String (plus vorangehendem Zählbyte). Es können beliebig viele Records hintereinanderstehen. Anhand der bekannten Größenangaben (4+1+10) lässt sich die Position jedes Records und auch die Position jedes Wertes darin berechnen. Solch ein Datenformat war damals nicht unüblich. Es ist kompakt und aufgrund der Positionsberechenbarkeit recht schnell im Zugriff. (Die Möglichkeit, dass ein String kein Zählbyte hat sondern mit einem Null-Byte abgeschlossen ist, erwähnte ich ja schon.)

        Die Frage ist nun erst einmal, ob du so ein Record-basierendes Format vorliegen hast. Die Struktur kann alle möglichen Formen annehmen. Genaueres fände man im Quellcode der zugehörigen Anwendung oder nur durch Probieren.

        echo "$verabschiedung $name";

        1. ok, das habe ich prinzipiell verstanden.
          Stellt sich für mich nur die Frage wie ich da weitermachen kann.
          Wie kann ich das testen?
          Und:nehmen wir mal an es handele sich um ein recordbasiertes Format...
          Wie kann ich das dann verarbeiten?
          Vielen dank

          1. echo $begrüßung;

            Stellt sich für mich nur die Frage wie ich da weitermachen kann.
            Wie kann ich das testen?

            Anschauen und Schlussfolgerungen ziehen. Diese in Code gießen, gegen den Datenbestand testen und gegebenenfalls weiter analysieren, Schlussfolgerungen ziehen, ...

            Und:nehmen wir mal an es handele sich um ein recordbasiertes Format...
            Wie kann ich das dann verarbeiten?

            Dateien lassen sich mit den üblichen Dateifunktionen lesen. Öffnen (gegebenenfalls im Binärmodus) und einen Block von Bytes lesen so groß sein sollte wie die Recordgröße. Solch einen Block dann weitergehend verarbeiten und mit dem nächsten Block weitermachen, bis zum Dateiende.

            Wie du den Block zerlegen musst kommt kommt darauf an, wie er aufgebaut ist. Da es unter PHP keine "echten" Arrays (z.B. Array of Bytes) gibt, bleiben dir nur mehr oder weniger die Stringfunktionen zum Zerschneiden der Blöcke.

            Alternativ kannst du auch jedes Byte einzeln aus der Datei lesen oder auch die Blockgröße entsprechend der Größe des jeweiligen Elements des Records wählen.

            Das sind aber alles nur theoretische Überlegungen, die auch aufgrund der tatsächlichen Datenlage nicht richtig sein müssen oder es dafür bessere Lösungen gibt. Genaueres kann man dir empfehlen, wenn du mal einen relevanten Hex-Dump-Ausschnitt der Daten zeigst.

            echo "$verabschiedung $name";