tech234: Gewissen Ausschnitt aus auszulesender CSV schneiden

Ich schreibe gerade einem Java-Programm für ein Studienprojekt, mit dem der Inhalt von CSV-Datein ausgelesen und angepasst werden soll. Begonnen habe ich schon, nur stehe ich jetzt vor dem Problem, dass ich nicht weiß, wie ich nur den gewünschten Content (Satz + Vote-Zahlen) filtern bzw. zumindest den letzten Teil (s. unten) herausschneiden kann:

PARENT,"Lorem ipsum...","3","0","Town","09:17, 29/11/2016"

REPLY,"Loren ipsum...”,"2","0","Town","09:18, 29/11/2016"

  1. Hallo und gute Nacht,

    was willst Du finden? Den Datensatz, oder bestimmte Teile des Datensatzes?

    CSV hat den Nachteil, dass Du die gesamte Datei durch den Streamfilter ziehen musst, um den Aufsetzpunkt zu finden, es sei denn, Du hättest dir schon einen Index angelegt mit den Aufsetzpunkten.

    Grüße
    TS

    --
    es wachse der Freifunk
    http://freifunk-oberharz.de
  2. Ich schreibe gerade einem Java-Programm für ein Studienprojekt, mit dem der Inhalt von CSV-Datein ausgelesen und angepasst werden soll. Begonnen habe ich schon, nur stehe ich jetzt vor dem Problem, dass ich nicht weiß, wie ich nur den gewünschten Content (Satz + Vote-Zahlen) filtern bzw. zumindest den letzten Teil (s. unten) herausschneiden kann:

    PARENT,"Lorem ipsum...","3","0","Town","09:17, 29/11/2016"

    REPLY,"Loren ipsum...”,"2","0","Town","09:18, 29/11/2016"

    Auch für Java-Programmierer gelten die von Niklas Wirth um 1980 getroffenen Feststellungen:

    • Dateien sind (Byte)Sequenzen
    • Sequenzen werden sequentiell gelesen
    • Sequenzen werden sequentiell geschrieben
    • Wahlfreier Zugriff (Random Access) findet nicht auf Dateiebene statt
    • Wahlfreier Zugriff wird über den Hauptspeicher (RAM) abgewickelt
    • Zwischen einer Sequenz und der darin transportierten Datenstruktur vermittelt ein (Serialize)Algorithmus

    Du willst wahlfreien Zugriff, MfG

    1. @@pl

      • Dateien sind (Byte)Sequenzen

      Textdateien[1] sind Sequenzen von Zeichen.

      Wie diese durch die Zeichencodierung auf Bytes abgebildet werden, ist für den Anwender hier völlig irrelevant.

      LLAP 🖖

      --
      „Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.“ —Johann Wolfgang von Goethe

      1. incl. Textformate wie CSV, HTML, XML, JSON, … ↩︎

      1. @@pl

        • Dateien sind (Byte)Sequenzen

        Textdateien[^1] sind Sequenzen von Zeichen.

        Wie diese durch die Zeichencodierung auf Bytes abgebildet werden, ist für den Anwender hier völlig irrelevant.

        Dateien kennen keine Zeichenkodierung. Sie sind einfach nur Bytesequenzen und das gilt auch für Textdateien. Der Dateibegriff nach Niklaus Wirth hat schon einen gewissen Sinn und auch Konsequenzen die von vielen heutigen Entwicklern fleißig ignoriert werden.

        MfG

        1. @@pl

          • Dateien sind (Byte)Sequenzen

          Textdateien[^1] sind Sequenzen von Zeichen.

          Wie diese durch die Zeichencodierung auf Bytes abgebildet werden, ist für den Anwender hier völlig irrelevant.

          Dateien kennen keine Zeichenkodierung. Sie sind einfach nur Bytesequenzen und das gilt auch für Textdateien.

          Du bist im Schichtenmodell eine Etage zu tief ausgestiegen. Komm rauf!

          LLAP 🖖

          --
          „Wenn du eine weise Antwort verlangst, musst du vernünftig fragen.“ —Johann Wolfgang von Goethe
          1. Moin ;

            Du bist im Schichtenmodell eine Etage zu tief ausgestiegen. Komm rauf!

            Sag mir lieber wie ich diesen faden Bytegeschmack wieder rauskriege ;)

            MfG

    2. Tach!

      Auch für Java-Programmierer gelten die von Niklas Wirth um 1980 getroffenen Feststellungen:

      • Dateien sind (Byte)Sequenzen

      Wir schreiben mittlerweile 2017 und die Systembibliotheken der meisten Programmiersprachen (Java gehört dazu) haben in ihren Textdatei-Lesefunktionen eine Möglichkeit zur Kodierungsangabe. Somit bekommt man die Daten zeichenbasiert und muss sich nicht mit deren Bytedarstellung rumschlagen.

      dedlfix.

      1. Tach!

        Auch für Java-Programmierer gelten die von Niklas Wirth um 1980 getroffenen Feststellungen:

        • Dateien sind (Byte)Sequenzen

        Wir schreiben mittlerweile 2017 und die Systembibliotheken der meisten Programmiersprachen (Java gehört dazu) haben in ihren Textdatei-Lesefunktionen eine Möglichkeit zur Kodierungsangabe. Somit bekommt man die Daten zeichenbasiert und muss sich nicht mit deren Bytedarstellung rumschlagen.

        Eben: Der Sinn von Schichtenmodellen. Was nichts aber auch gar nichts am Wirth'schen Dateibegriff ändert und das Schichtenmodell hat er ja auch beschrieben. Ob jedoch am Data-Access-Layer oder explizit im Programm zwischen Bytesmantic/Charactersemantic umgeschaltet wird ist völlig nebensächlich.

        Es führt erfahrungsgemäß eher zu Missverständnissen wenn bereits am DAL die Zeichenkodierung ins Spiel kommt und oftmals auch zu mehr Aufwand wenn Legacy-Code überwiegend byteorientiert ist.

        MfG

  3. Tach!

    Ich schreibe gerade einem Java-Programm für ein Studienprojekt, mit dem der Inhalt von CSV-Datein ausgelesen und angepasst werden soll. Begonnen habe ich schon, nur stehe ich jetzt vor dem Problem, dass ich nicht weiß, wie ich nur den gewünschten Content (Satz + Vote-Zahlen) filtern bzw. zumindest den letzten Teil (s. unten) herausschneiden kann:

    Nimm einen CSV-Parser. Die gibt es auch für Java.

    CSV sieht zwar auf den ersten Blick einfach aus, hat dann aber doch ein paar Regeln, die zu beachten sind. Zum Beispiel: Strings können mit einem Begrenzungszeichen eingerahmt werden. Wenn dieses Bestandteil des Strings ist, muss es doppelt hingeschrieben werden. Feldbegrenzer können innerhalb eingerahmter Strings vorkommen, weswegen man nicht einfach an diesen die Felder trennen kann. Zeilenenden können auch Bestandteil von eingerahmten Strings sein. Weswegen man nicht einfach am Zeilenumbruch die Datensätze trennen kann.

    So zumindest, wenn du universelles CSV lesen können möchtest. Wenn diese Sonderfälle bei dir nicht auftreten können, dann geht auch Splitten und Trimmen, um an die Werte zu kommen.

    dedlfix.

    1. Ich würde gerne nur den Inhalt und die Bewertungszahlen (die zwei einzelnen Zahlen) herausschneiden. Nur die Zeile ohne Zeichen herauszuschneiden, kann ich schreiben. Aber wie ich diese Infos daraus filtern soll, das weiß ich halt nicht.

      1. Ich würde gerne nur den Inhalt und die Bewertungszahlen (die zwei einzelnen Zahlen) herausschneiden. Nur die Zeile ohne Zeichen herauszuschneiden, kann ich schreiben. Aber wie ich diese Infos daraus filtern soll, das weiß ich halt nicht.

        Genau dafür brauchst Du den wahlfreien Zugriff. I.d.R. macht ein Serializer aus einer CSV-Datei ein Array. Somit wirst Du auf die gewünschten Elemente eines Arrays zugreifen und eben das spielt sich im Hauptspeicher ab. Und nachdem das Array bearbeitet wurde, kann die Datei neu geschrieben werden.

        MfG

      2. Tach!

        Ich würde gerne nur den Inhalt und die Bewertungszahlen (die zwei einzelnen Zahlen) herausschneiden. Nur die Zeile ohne Zeichen herauszuschneiden, kann ich schreiben. Aber wie ich diese Infos daraus filtern soll, das weiß ich halt nicht.

        Wie ich (in kurz) schrieb: Ausgehend, dass keine Sonderregeln vorkommen, Splitten an den Trennzeichen. Zuerst am Zeilenumbruch, damit bekommst du ein Array mit den Datensätzen. Dann jeden Datensatz am Feldtrenner Splitten, und du bekommst ein Array mit den Feldern. Von den Felder mit einer Trim-Funktion die Begrenzer (Anführungszeichen) entfernen. Fertig sind die Rohdaten.

        Aber wie auch gesagt, nimm lieber eine fertige Bibliothek, die auch die Sonderregeln beachtet - vor allem auch beim Erstellen der Daten. Ich hab auch schon kaputte zum Verarbeiten CSV bekommen, bei denen der Ersteller die Sonderregeln und dazu noch misachtet hat, dass der Anwender CSV-spezifische Zeichen innerhalb der Daten einfügen konnte. Sowas kann man dann nicht mehr wirklich automatisch parsen, weil man die Felder nicht auseinanderhalten kann.

        dedlfix.

  4. Hallo und guten Morgen,

    guckst Du einfach mal bei Google unter "Java CSV Parser" und bekommst komplette Lösungen:

    https://www.mkyong.com/java/how-to-read-and-parse-csv-file-in-java/

    Nur verstehen musst Du es noch selber ;-)

    Grüße
    TS

    --
    es wachse der Freifunk
    http://freifunk-oberharz.de
    1. guckst Du einfach mal bei Google unter "Java CSV Parser" und bekommst komplette Lösungen:

      https://www.mkyong.com/java/how-to-read-and-parse-csv-file-in-java/

      Habe ich schon vor ein paar Tagen gefunden. Trotzdem danke. :) Der Inhalt ist wie oben angegeben, weshalb ich auch Kommata und Anführungszeichen in meinen einzelnen Bereichen der Zeile haben kann. Dann wäre, würde ich nach Kommas oder Anführungszeichen teilen oder sortieren, das Ergebnis unbrauchbar für mich, da der Inhalt, also das wesentliche, nicht korrekt wäre. Ich könnte nur bestimmen, was vor und nach dem Inhalt kommt, da das mir bekannte Strings sind. (bspw. PARENT oder Stadt-Name, ist nur eine Stadt)

      1. Tach!

        Der Inhalt ist wie oben angegeben, weshalb ich auch Kommata und Anführungszeichen in meinen einzelnen Bereichen der Zeile haben kann. Dann wäre, würde ich nach Kommas oder Anführungszeichen teilen oder sortieren, das Ergebnis unbrauchbar für mich, da der Inhalt, also das wesentliche, nicht korrekt wäre.

        Dann nimm einen fertigen Parser, oder ist die Aufgabe, einen solchen zu schreiben?

        Wenn ja, ist eine Vorgehensweise, Zeichen für Zeichen zu lesen und sich den Zustand zu merken, woraufhin für das nächste Zeichen entscheiden werden kann, wie mit ihm zu verfahren ist. Teilweise musst du die Zeichen hinter dem aktuellen berücksichtigen oder alternativ entsprechende Merker in den Zustandsspeicher setzen. Beispielsweise kann ein Anführungszeichen im Zustand "mit Anführungszeichen begonnener String" das Ende bedeuten, wenn ein Feld- oder Zeilenseparator folgt, oder ein literales Anführungszeichen darstellen, wenn ein weiteres folgt, oder einen Fehler in den Daten, wenn ein anderes Zeichen folgt.

        dedlfix.

    2. hi,

      Bei der genannten Aufgabenstellung liegt der Dateiinhalt idealerweise auf einem Array mit Objekten. Wobei jede Zeile ein Objekt ergibt, d.h., zur Lösung der Aufgabe wären ganz einfach nur die jeweiligen Eigenschaften eines Objekts zu löschen.

      guckst Du einfach mal bei Google unter "Java CSV Parser" und bekommst komplette Lösungen:

      https://www.mkyong.com/java/how-to-read-and-parse-csv-file-in-java/

      Ggf. wird aus einem Array mit Arrays ein Array mit Objekten gemacht. CSV abstrahiert ja eine Tabelle bzw. tabellarische Daten, d.h., ein Spaltenname wäre eine Eigenschaft.

      MfG

      1. guckst Du einfach mal bei Google unter "Java CSV Parser" und bekommst komplette Lösungen:

        https://www.mkyong.com/java/how-to-read-and-parse-csv-file-in-java/

        Ggf. wird aus einem Array mit Arrays ein Array mit Objekten gemacht. CSV abstrahiert ja eine Tabelle bzw. tabellarische Daten, d.h., ein Spaltenname wäre eine Eigenschaft.

        Okay, das mit den Spaltennamen wäre ein Ansatz. Oben stehen folgende:

        post_type,"message","up_votes","down_votes","city","date"

        Wie könnte da ansetzen?

        1. guckst Du einfach mal bei Google unter "Java CSV Parser" und bekommst komplette Lösungen:

          https://www.mkyong.com/java/how-to-read-and-parse-csv-file-in-java/

          Ggf. wird aus einem Array mit Arrays ein Array mit Objekten gemacht. CSV abstrahiert ja eine Tabelle bzw. tabellarische Daten, d.h., ein Spaltenname wäre eine Eigenschaft.

          Okay, das mit den Spaltennamen wäre ein Ansatz. Oben stehen folgende:

          post_type,"message","up_votes","down_votes","city","date"

          Wie könnte da ansetzen?

          Du brauchst die Tabelle im Speicher. Guck doch mal, was Java an API's für CSV so hat. Idealerweise hast Du:

          // Abstrakter Datentyp
          jede zeile => {
            "post_type"  => 'foo',
            "message"    => 'bar',
            "up_votes"   => '1',
            "down_votes" => '2',
            "city"       => 'NYC',
            "date"       => '9/11'
          }
          

          Und musst da nur die Einträge "message","up_votes","down_votes" löschen. Danach gehts zurück in die Datei.

  5. Hallo und guten Morgen,

    wer suchet, der findet. Das sieht doch gut aus:

    http://stackoverflow.com/questions/101100/csv-api-for-java

    Welche IDE auf welchem OS benutzt Du denn für die Java-Entwicklung?

    Grüße
    TS

    --
    es wachse der Freifunk
    http://freifunk-oberharz.de
    1. Welche IDE auf welchem OS benutzt Du denn für die Java-Entwicklung?

      Ich nutze momentan die aktuellste Version von Netbeans auf macOS Sierra 10.12.1.