2016-12-28 4 views
0

Ich habe einige Probleme mit einem Befehl.Java Csv-data Zeichenfolge Raumaufteilung Fehler

Ich habe eine Datei des Typs csv, die wie folgt aussieht:.

Merkmals-Nr; Interne Teile-Nr; Bereich; Fertigungsschritt; ...

Nach dem Lesen der Datei in wollen. eine Zeile lesen und dann die Zeile nach ";" mit dieser Codezeile.

List<String> datenListe = Arrays.asList(data.split(";")); 

Dann mache ich ein system.println

Wie der Druck aussehen sollte:
Merkmals-Nr.
Interne Teile-Nr.
Bereich
Fertigungsschritt
...

Wie der Druck tatsächlich aussieht:
Merkmals-Nr.
Interne

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 
    at java.util.Arrays$ArrayList.get(Arrays.java:2866) 
    at CsvEinlesen.main(CsvEinlesen.java:23) 

Ich fand heraus, dass das Problem durch den Raum verursacht wird "Interne Teile-Nr." aber ich weiß nicht, wie ich das Problem mit den Räumen lösen soll.

Dies ist thecomplete Code:

import java.io.*; 

import java.util.*; 


public class CsvEinlesen { 
    public static void main(String[] args) { 
    String fileName = "0-201-08-4473.csv"; 
    File file = new File(fileName); 

    try { 
     Scanner csvInputStream = new Scanner(file); 

     while (csvInputStream.hasNext()) { 
     String data = csvInputStream.next(); 

     List<String> datenListe = Arrays.asList(data.split(";")); 

     for (int i = 0; i < 32; i++) { 
      System.out.println(datenListe.get(i)); 
     } 
     } 

     csvInputStream.close(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
     System.out.println("CSV-Datei nicht gefunden"); 
    } 
    } 
} 

Antwort

0

Ist es wirklich notwendig, um das Array zu einem List<String> wenn Sie noch durch sie wie ein normales Array iterieren zu konvertieren? Auch warum haben Sie 32 als Grenze gesetzt? Dies ist nicht sicher - genau, weil Sie am Ende Fehler wie ArrayIndexOutOfBoundsException bekommen werden.

Mein Vorschlag, für dieses Beispiel ist wie diese mit dem Array zu arbeiten:

//the rest of your code... 
    while (csvInputStream.hasNext()) { 
      String data = csvInputStream.next(); 

      String[] wordsInLine = data.split(";"); 

      for (int i = 0; i < wordsInLine.length; i++) { 
       System.out.println(wordsInLine[i]); 
      } 
      } 
    //the rest of your code ... 

geben, dass ein Versuch und sehen, ob der Fehler verschwindet.

+0

Dank Ihres Codes wurde ein Teil des Problems gelöst. Das andere Problem mit den Leerzeichen habe ich mit dem Befehl 'code' behoben. Scanner.useDelimiter ("; "); – Gusse

+0

Tolles Zeug - gut gemacht. Ich helfe gern. Glückliche Kodierung! – ishmaelMakitla

0

Ich arbeitete heute an einer ähnlichen Aufgabe (Lesen von Daten aus einer CSV, aber mit "," Trennzeichen). Wenn Sie daran interessiert sind, die Reihenfolge der Felder beizubehalten, und Sie wissen, wie viele "Spalten" Sie haben werden, möchten Sie vielleicht eine Lösung mit einem Regexp versuchen.

Gründe, dies zu tun:

  • , wenn sie mit Verfahren .split() für die Linie Wert1 ;;; Wert2 Aufspalten ;; Sie erhalten ein Array wie: arr [0]: value1, arr [1]: value2. Dies könnte nicht wirklich in Ordnung sein, weil Sie vielleicht wissen möchten, was dieser Wert darstellt, und Sie könnten einen Hinweis haben, wenn Sie die Reihenfolge in der CSV kennen, aber Sie verlieren diese Informationen auf diese Weise.
  • Verwenden Sie eine Regexp wie die, die ich im Beispiel zeigen werde , um die Reihenfolge der CSV-Werte zu respektieren, und Sie können die Ergebnisse zu was auch immer Sie möchten, ein Array von Strings, ArrayList hinzufügen Liste und so weiter (weil Sie nach ArrayList gefragt haben, werde ich das Beispiel verwenden)
  • Sie könnten lernen, Gruppe in Regexp verwenden, um genauere Informationen zu erhalten, und könnte auch mehr spezifische reg exps je nach Ihren Bedürfnissen zu bauen

Nachteile:

  • vielleicht ist es keine effiziente Art und Weise, in der Bedeutung von Zeit
  • Sie es selbst spalten wählen könnte mit „.nextIndexOf (separatingChar)“
  • die Spur der Werte zu halten
  • vielleicht sogar andere , ich weiß nicht,

aber hier ist meine Lösung:

public class RegExpSeparator { 
    // if you have a convention for your CSV or file, that the first row 
    // will contain the header you might count the header items and update the 
    // column count so this method will be more generic 
    // also to be more generic you can make a final var to store the separator 
    // and append it to the stringbuilder in the method splitRow 
    public static int columnCount = 7; 

    public static void main(String args[]) { 
     String testRow1 = "NaMe_wE132;-123.46;CEE Tue 23 Apr 1976 22:23:34;Value;Another_value;bla;blaa"; 
     String testRow2 = ";;Value1;;;;Value2"; 

     ArrayList<String> letsTestFirstCase = new ArrayList<String>(splitRow(testRow1)); 
     for (String item : letsTestFirstCase) { 
      System.out.print(item + ";"); // we'll add and ; also at the end 
     } 
     System.out.println(""); 
     ArrayList<String> letsTestSecondCase = new ArrayList<String>(splitRow(testRow2)); 
     for (String item : letsTestSecondCase) { 
      System.out.print(item + ";"); // we'll add and ; also at the end 
     } 
    }  

    private static ArrayList<String> splitRow (String toSplit) { 
     StringBuilder buildPattern = new StringBuilder(); 
     //use this if you know how many columns you'll have, from the start 
     for (int i = 0; i<columnCount-1; i++) { 
      buildPattern.append("([^;]*);"); // to keep it simple I've assumed the fact that 
      // you might have values like "Name_233, 23:45 PM, -123.45" and so on 
      // * means 0 or more occurences of any char except for ; 
     } 
     buildPattern.append("([^;]*)"); //the last column will not be followed by a separator 
     // the final regexp will be something like 
     // (group1);(group2);...;(groupN) 
     // and you might get the values by calling matcher.group(i) 
     // where i will have values in the interval [1,N] 
     // group(0) will return the WHOLE STRING!! 
     String patternToString = buildPattern.toString(); 
     Pattern pattern = Pattern.compile(patternToString); 
     Matcher matcher = pattern.matcher(toSplit); // get a matcher object 

     ArrayList<String> result = new ArrayList<String>(); 
     if (matcher.find()) { 
      for (int i=1; i<=columnCount; i++){ 
       result.add(matcher.group(i)); // for the columns like ;; it will add the string "" 
      } 
     } else { 
      System.out.println("Could not parse the given row"); 
     } 
     return result; 
    } 
} 

Sie mehr über regexp mit Beispielen fr lernen om TutorialsPoint.

HINWEIS: Sie sollen das als eine separate Klasse machen, wie ein util/Handler ein, machte es nur auf diese Weise sowohl Haupt- und die Methode hier aus Gründen des Beispiels zu haben. Viel Glück!