# Datei (CSV-ähnlich) in Java einlesen & mit teil der Daten Graphen erstellen



## kakulala (13. Jul 2017)

Hallo Leute,
ich habe folgendes Problem. Ich soll eine Datei einlesen, die augenscheinlich eine CSV-Datei ist, aber zwischen den Spalten verstecken sich auch noch andere Trennungszeichen....
Nun soll ich also die Datei einlesen (Export.csv) die erste "spalte" löschen und mit den Werten aus Spalte 2 & 3 einen Graphen erstellen. 

Die Datei sieht folgendermaßen aus (beispielhaft jetzt nur 3 Zeilen):
2017-07-12T07:02:53+00:00,2017-07-12T09:02:53+02:00,26.25
2017-07-12T08:02:54+00:00,2017-07-12T10:02:54+02:00,26.08
2017-07-12T09:02:55+00:00,2017-07-12T11:02:55+02:00,25.78 

Den ersten Teil "2017-07-12T07:02:53+00:00" würde ich gerne löschen, vom zweiten Teil ist nur die Uhrzeit wichtig "2017-07-12T*09:02:53*+02:00" und die dritte Spalte ganz "26.25".
Anschließend würde ich gerne die Uhrzeit und die Temperatur in einem Graphen darstellen.

Ich weiß leider überhaupt nicht wie ich anfangen soll....sowie ich das verstanden habe brauche ich den BufferedReader zum Einlesen der Datei & am besten wäre es sie zeilenweise einzulesen. Aber wie lösche ich denn genau den ersten Teil der Zeile & wie kann ich auf die anderen Teile zugreifen??
Für die graphische Darstellung ist es sinnvoller ein Framework ( jFreeChart) zu benutzen oder geht das auch darstellen von Graphen mit den ausgelesenen Daten auch anders?
Danke für hilfreiche Antworten!!


----------



## Robat (13. Jul 2017)

Das einlesen kannst du, wie du bereits richtig gesagt hast, bspw. mit einem BufferedReader machen.

Wenn du die Datei nun Zeile für Zeile einliest, kannst du ja selber bestimmen welche Abschnitte der Zeile du verwirfst und welche du abspeichern willst.
Du könntest erstmal sagen dass du die Zeile am Komma splittest. Dann hättest du ein Array mit 3 Teilen: `2017-07-12T07:02:53+00:00`, `2017-07-12T09:02:53+02:00` und `26.25`. 

Das 1. Array-Element benutzt du einfach nicht weiter.
Beim 2. Element könntest du dir die Uhrzeit mit einem regulären Ausdruck rausfiltern. (Gibt auch noch andere Möglichkeiten wie bspw. am *T* und am *+* splitten).
Das 3. Element kannst du so lassen wie es ist.

Jetzt nimmst du deine Datenstruktur (welcher Art auch immer) zur Hand und speicherst die beiden Werte darin. Das machst du für jede Zeile und schon hast du deine Uhrzeit / Temperatur 

Ob du für die Darstellung ein Framework benutzt oder es selber zeichnest ist deine Entscheidung. Beides sollte nicht so schwer sein.


----------



## kakulala (13. Jul 2017)

Okay, schonmal vielen Dank! Ich bin noch nicht soo erfahren mit Java & versuch mir möglichst viel beizubringen. Also das einlesen & splitten hat schonmal geklappt. Einlesen mit BufferedReader. Jetzt habe ich aber eine ArrayList verwendet, da ich nicht genau weiß wieviel bzw wie groß die Datei wird bzw werden soll
Sieht dann so aus:

```
//Splitten am Komma
    final String[][] valuesArray = new String[lines.size()][];
    int cnt = 0;
    for (final String line : lines) {
        valuesArray[cnt++] = line.split(",");
    }

 
    // Ausgabe des eingelesenen Arrays
    for (String[] arr : valuesArray) {
        System.out.println(Arrays.toString(arr));
    }
```

Jetzt kann ich aber nicht die Liste noch splitten oder? Also spaltenweise? Was meinst du denn mit regulären Ausdrücken rausfiltern? Hab damit noch nicht wirklich was zutun gehabt...kannst du das kurz erklären?


----------



## Flown (13. Jul 2017)

Einfach mit:

```
String input = "2017-07-12T07:02:53+00:00,2017-07-12T09:02:53+02:00,26.25\n" +
  "2017-07-12T08:02:54+00:00,2017-07-12T10:02:54+02:00,26.08\n" +
  "2017-07-12T09:02:55+00:00,2017-07-12T11:02:55+02:00,25.78 ";
try(StringReader sr = new StringReader(input);
    BufferedReader reader = new BufferedReader(sr)) {
  String line;
  while((line = reader.readLine()) != null) {
    String[] split = line.split(",");
    System.out.println(ZonedDateTime.parse(split[1]).format(DateTimeFormatter.ISO_LOCAL_TIME) + "," + split[2]);
  }
} catch (IOException e) {
  e.printStackTrace();
}
```


----------



## kakulala (13. Jul 2017)

Danke, aber du definierst jetzt ja den String input...im Idealfall geht das ja nicht, da die Datei eingelesen werden soll & es dann nicht möglich ist, den input zu definieren. Oder hab ich da jetzt was falsch verstanden bei deinem Code?


----------



## Flown (13. Jul 2017)

Dann übergibst du dem BufferedReader einfach einen FileReader? Ein wenig Eigeninitiative ist schon gefragt.


----------



## kakulala (13. Jul 2017)

Danke! Hab das ursprünglich ein bisschen anders gemacht. Wie gesagt, bin noch ned soo lange dabei mir das beizubringen. Dürfte jetzt aber so passen: 


```
FileReader myFile = null;
    BufferedReader buff = null;
    final ArrayList<String> lines = new ArrayList<String>();
    try {
        myFile = new FileReader("C:/Users/......./Desktop/Datei.csv");
        buff = new BufferedReader(myFile);
        String line;
        //Überspringen der ersten Zeile, da nichts wichtiges drinsteht
        buff.readLine();//erste Zeile lesen
       
       
        while ((line = buff.readLine()) != null) {
           
            //Splitten der Datei am Komma
            //Da Array bei [0] beginnt und das wegfallen soll, beginne bei eins
            String[] split = line.split(",");
             System.out.println(ZonedDateTime.parse(split[1]).format(DateTimeFormatter.ISO_LOCAL_TIME) + "," + split[2]);
           
            // Anzeige was eingelesen wurde
            // System.out.println(line);
            lines.add(line);
```


Hast du denn noch ein Beispiel wie man das mit regulären Ausdrücken lösen könnte? Oder ein allgemeines, wie ich damit filtern kann?


----------



## Harry Kane (13. Jul 2017)

kakulala hat gesagt.:


> Hast du denn noch ein Beispiel wie man das mit regulären Ausdrücken lösen könnte? Oder ein allgemeines, wie ich damit filtern kann?


Ich glaube nicht, dass dein Problem (Datei zeilenweise einlesen, an einem Trennzeichen splitten, dann die Teile einzeln vcerwerfen oder weiterverarbeiten) mit regulären Ausdrücken einfacher gelöst werden kann.
Zum erstellen von Charts kann ich JFreeChart wärmstens empfehlen.


----------



## mrBrown (13. Jul 2017)

kakulala hat gesagt.:


> Hast du denn noch ein Beispiel wie man das mit regulären Ausdrücken lösen könnte? Oder ein allgemeines, wie ich damit filtern kann?


Ein passender Regulärer Ausdruck dafür wäre zB `.*,.*(\d{2}:\d{2}:\d{2}).*,.*(\d{2}\.\d{2})`.
Der erste Ausdruck in Klammern matcht auf die Uhrzeit, der zweite in Klammern auf die Temperatur.

Für deinen UseCase ginge das zB mit:


```
Pattern pattern = pattern.compile(".*,.*(\\d{2}:\\d{2}:\\d{2}).*,.*(\\d{2}\\.\\d{2})");
Matcher matcher = pattern.matcher("2017-07-12T07:02:53+00:00,2017-07-12T09:02:53+02:00,26.25")
if (matcher.find()) {
  System.out.println(ZonedDateTime.parse(matcher.group(1)).format(DateTimeFormatter.ISO_LOCAL_TIME) + ", " + matcher.group(2));
}
```


----------



## JStein52 (14. Jul 2017)

Wenn du es so machst kompiliert es erstens fehlerfrei und läuft auch ohne Exception :

```
Pattern pattern = Pattern.compile(".*,.*(\\d{2}:\\d{2}:\\d{2}).*,.*(\\d{2}\\.\\d{2})");
        Matcher matcher = pattern.matcher("2017-07-12T07:02:53+00:00,2017-07-12T09:02:53+02:00,24.25");
        if (matcher.find()) {
            System.out.println(matcher.group(1) + ", " + matcher.group(2));
        }
```
 und die Temperatur darf nicht unter 10° fallen es werden nämlich Temperaturen im zweistelligen Bereich erwartet.


----------

