2016-12-28 57 views
0

我遇到了一些命令的麻烦。Java Csv-数据字符串空间拆分错误

我有型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。
上网。

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

我想通了,这个问题是由在空间造成“上网。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()为线VALUE1分裂时;;; VALUE2 ;; 你会得到一个像这样的数组:arr [0]:value1,arr [1]:value2。这可能是 不是真的好,因为你可能想知道 代表什么值,如果你知道它在 CSV中的顺序,你可能会有提示,但是你会以这种方式丢失这些信息。
  • 使用像我将在例子显示,你就可以 尊重CSV值的顺序,你可能 添加的结果,不管你喜欢一个正则表达式,字符串,ArrayList的数组,列表等
  • 你可以学习如何使用组中的正则表达式来获得更具体的信息(因为你问的ArrayList我会使用让这个例子),并 还可以建立更具体的REG EXPS根据您的需要

缺点:

  • 也许这不是一个有效的方式,你可以选择使用 自行拆它的时候
  • 的含义“.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; 
    } 
} 

您可以了解更多关于正则表达式举例FR om TutorialsPoint.

注意:你应该把它作为一个单独的类,就像util/handler一样,只是为了这个例子使它成为main和method。祝你好运!