2011-10-10 38 views
6

Tôi đang cố gắng nhập khẩu CSV tập tin để sử dụng ArraylistStringTokenizer:JAVA - Nhập CSV để ArrayList

public class Test 
{ 
    public static void main(String [] args) 
    { 
    List<ImportedXls> datalist = new ArrayList<ImportedXls>(); 

    try 
    { 
     FileReader fr = new FileReader("c:\\temp.csv"); 
     BufferedReader br = new BufferedReader(fr); 
     String stringRead = br.readLine(); 

     while(stringRead != null) 
     { 
     StringTokenizer st = new StringTokenizer(stringRead, ","); 
     String docNumber = st.nextToken(); 
     String note = st.nextToken(); /** PROBLEM */ 
     String index = st.nextToken(); /** PROBLEM */ 

     ImportedXls temp = new ImportedXls(docNumber, note, index); 
     datalist.add(temp); 

     // read the next line 
     stringRead = br.readLine(); 
     } 
     br.close(); 
    } 
    catch(IOException ioe){...} 

    for (ImportedXls item : datalist) { 
     System.out.println(item.getDocNumber()); 
    } 
    } 
} 

Tôi không hiểu làm thế nào nextToken công trình, bởi vì nếu tôi giữ khởi tạo ba biến (docNumber, noteindex) như nextToken(), nó không thành công trên:

Exception in thread "main" java.util.NoSuchElementException 
    at java.util.StringTokenizer.nextToken(Unknown Source) 
    at _test.Test.main(Test.java:32) 

Nếu tôi giữ docNumber chỉ, nó hoạt động. Bạn có thể giúp tôi?

+2

Tại sao bạn không sử dụng 'stringRead.split (", ")'? – Thomas

+0

Hiển thị một dòng tiêu biểu – duffymo

+0

Thư viện opencsv giúp đọc các tệp csv rất dễ dàng, không cần mã của riêng bạn. – Pete855217

Trả lời

18

Dường như một số hàng trong tệp đầu vào của bạn có ít hơn 3 trường được phân cách bằng dấu phẩy.Bạn nên luôn kiểm tra xem mã thông báo có nhiều mã thông báo hơn không (StringTokenizer.hasMoreTokens), trừ khi bạn chắc chắn 100% đầu vào của mình là chính xác.

Phân tích cú pháp CORRECT tệp CSV không phải là nhiệm vụ tầm thường. Tại sao không sử dụng thư viện có thể làm rất tốt - http://opencsv.sourceforge.net/?

+0

Bạn cũng đúng, vấn đề nằm trong tệp CSV! Cảm ơn bạn cho openCsv, tôi cũng sẽ thử :-) – gaffcz

+0

go for opencsv. chỉ cần tưởng tượng, điều gì sẽ xảy ra với mã, bạn sắp sử dụng, nếu trường 'ghi chú' sẽ chứa dấu phẩy. Một câu hỏi khác @stackoverflow? :) – aav

+0

Lời khuyên của bạn cuối cùng là thuận tiện nhất, cảm ơn bạn rất nhiều! (và đừng lo lắng, các câu hỏi tiếp theo sẽ sớm xuất hiện: D – gaffcz

2

Có vẻ như mã của bạn đang đi đến một dòng mà Trình mã hóa chỉ chia nhỏ thành 1 phần thay vì 3. Có thể có các dòng có dữ liệu bị thiếu không? Nếu vậy, bạn cần phải xử lý này.

+0

Bạn nói đúng, vấn đề nằm trong tệp CSV! Cảm ơn bạn :-) – gaffcz

2

Có thể tệp nhập liệu của bạn không chứa phần tử khác được giới hạn bởi , trong ít nhất một dòng. Vui lòng cho chúng tôi thấy thông tin của bạn - nếu có thể dòng không thành công.

Tuy nhiên, bạn không cần sử dụng StringTokenizer. Sử dụng String#split() có thể được dễ dàng hơn:

... 
while(stringRead != null) 
{ 
    String[] elements = stringRead.split(","); 

    if(elements.length < 3) { 
     throw new RuntimeException("line too short"); //handle missing entries 
    } 

    String docNumber = elements[0]; 
    String note = elements[1]; 
    String index = elements[2]; 

    ImportedXls temp = new ImportedXls(docNumber, note, index); 
    datalist.add(temp); 

    // read the next line 
    stringRead = br.readLine(); 
} 
... 
+0

Cảm ơn bạn, đó là nó! Tệp CSV không có ba cột ở khắp mọi nơi .. Bây giờ tôi đang cố gắng sử dụng mã của bạn :-) – gaffcz

2

Bạn sẽ có thể kiểm tra thẻ của bạn sử dụng phương pháp() các hasMoreTokens. Nếu điều này trả về false, thì có thể dòng bạn đã đọc không chứa bất kỳ thứ gì (ví dụ: một chuỗi trống).

Sẽ tốt hơn nếu sử dụng phương thức String.split() - nếu tôi không nhầm, có kế hoạch từ chối lớp StringTokenizer.