2016-12-28 12 views
0

У меня возникли проблемы с командой.Java Csv-data Ошибка разбиения пространства строк

У меня есть файл типа CSV, который выглядит следующим образом:.

Merkmals-Nr; интерн TEILE-Nr; Bereich; Fertigungsschritt; ...

После прочтения файла в это нужно. прочитать одну строку, а затем разделить строку после «;» используя эту кодолинку.

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

Тогда я делаю system.println

Как печать должна выглядеть:
Merkmals-Nr.
Interne Teile-Nr.
Bereich
Fertigungsschritt
...

Как печать выглядит на самом деле:
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) 

я понял, что проблема вызвана пространства в "Interne TEILE-Nr." но я не знаю, как решить проблему с пробелами.

Это thecomplete код:

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"); 
    } 
    } 
} 

ответ

0

Является ли это действительно необходимо, чтобы преобразовать массив в List<String>, если вы все еще итерацию через него, как обычный массив? Также почему вы поставили 32 в качестве предела? Это небезопасно - именно потому, что вы получите ошибки, такие как ArrayIndexOutOfBoundsException.

Мое предложение, для этого примера, чтобы просто работать с массивом, как это:

//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 ... 

Дайте что попробовать и посмотреть, если ошибка уходит.

+0

Спасибо, что ваш код решил одну часть проблемы. Другая проблема с пробелами, которые я исправил с помощью команды 'code' scanner.useDelimiter ("; "); – Gusse

+0

Отличный материал. Я рад помочь. Счастливое кодирование! – ishmaelMakitla

0

Я работал сегодня над подобной задачей (чтение данных из CSV, но с разделителем «,»). Если вы заинтересованы в сохранении порядка полей, и знаете, сколько «столбцов» у вас будет, вы можете попробовать решение с регулярным выражением.

Причины для этого:

  • при разделении с помощью метода .split() для линии значению1 ;;; значение2 ;; вы получите массив вроде: arr [0]: значение1, arr [1]: значение2. Это может быть не очень-то нормально, потому что вы можете узнать, что это за значение , и вы можете иметь подсказку, если знаете свой заказ в CS, но таким образом вы теряете эту информацию.
  • Используя регулярное выражение, подобное тому, которое я покажу в примере, вы сможете уважать порядок значений CSV, и вы можете добавить результаты в любое удобное для вас количество строк, ArrayList, Список и т. Д. (потому что вы попросили ArrayList, я сделаю пример, используя это).
  • Вы можете научиться использовать группу в regexp для получения более подробной информации, а также может создавать более специфичные регистры, в зависимости от ваших потребностей

Минусы:

  • может быть, это не самый эффективный способ, в значениях времени
  • вы могли выбрать, чтобы разделить его самостоятельно, используя «.nextIndexOf (separatingChar)», чтобы быть в курсе значений
  • может быть, даже другие я не знаю

Однако, вот мое решение:

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; 
    } 
} 

Вы можете узнать больше о регулярных выражений с примерами из TutorialsPoint.

ПРИМЕЧАНИЯ: Вы должны сделать это как отдельный класс, как UTIL/обработчик одного, только что сделал это таким образом, чтобы иметь как основные и методы здесь ради примера. Удачи!