2012-11-14 2 views
0

CSV 파일을 ArrayList 또는 String [] [] 배열로 읽으려고합니다. 이 목록에서 그것을 읽고 목록 배열, tokenizer 사용하여 배열에 노력하고있어. csv 파일에는 7 개의 열 (A - G)과 961 개의 행 (1-961)이 있습니다.타사 라이브러리가없는 CSV 파일 읽기

public class FoodFacts 
{ 
    private static BufferedReader textIn; 
    private static BufferedReader foodFacts; 
      static int numberOfLines = 0; 
      static String [][] foodArray; 
    public static String aFact; 
    static int NUM_COL = 7; 
    static int NUM_ROW = 961; 
    // Make a random number to pull a line 
    static Random r = new Random(); 

    public static void main(String[] args) 
    { 
     try 
     { 
      textIn = new BufferedReader(new InputStreamReader(System.in)); 
      foodFacts= new BufferedReader(new FileReader("foodfacts.csv")); 
      Scanner factFile = new Scanner(foodFacts); 
      List<String> facts = new ArrayList<String>(); 

      String fact; 
      System.out.println("Please type in the food you wish to know about."); 
      String request = textIn.readLine(); 
      while (factFile.hasNextLine()){ 
       fact = factFile.nextLine(); 
       StringTokenizer st2 = new StringTokenizer(fact, ","); 
       //facts.add(fact); 
       numberOfLines++; 
       while (st2.hasMoreElements()){ 
        for (int j = 0; j < NUM_COL ; j++) { 
         for (int i = 0; i < NUM_ROW ; i++){ 
          foodArray [j][i]= st2.nextToken(); //NULL POINTER HERE 
          System.out.println(foodArray[j][i]); 
         } 
        } 
       } 
      } 
     } 
     catch (IOException e) 
     { 
      System.out.println ("Error, problem reading text file!"); 
      e.printStackTrace(); 
     } 
    } 
} 
+0

"CSV"라는 몇 가지 형식 중 어느 것을 읽고 싶습니까? – Raedwald

+0

그것의 엑셀? 쉼표로 구분 된 값 –

+0

타사 라이브러리가 없으면 이것을 수행해야합니까? –

답변

3

이 그것을 사용하기 전에 foodArray = new String[NUM_ROW][NUM_COL];foodArray를 초기화 .. 내는 2 차원 배열에 대한 루프 널 포인터를 반환 유지,하지만 난 그것을 작동한다고 생각합니다.

또한 한 번에 한 행씩 읽는 중 for 루프 은 필요하지 않습니다. 행으로

사용 numberOfLines : 또는

 while (factFile.hasNextLine() && numberOfLines < NUM_ROW){ 
       fact = input.nextLine(); 
       StringTokenizer st2 = new StringTokenizer(fact, ",") ; 
       //facts.add(fact); 
       while (st2.hasMoreElements()){ 
        for (int j = 0; j < NUM_COL ; j++) { 
        foodArray [numberOfLines][j]= st2.nextToken(); 
        System.out.println(foodArray[numberOfLines][i]); 
       } 
       } 
       numberOfLines++; 
      } 

, 난 당신이 모든 열을에 한 번, 예를 들어 얻을 split을 사용할 수있을 것 같아요

 while (factFile.hasNextLine() && numberOfLines < NUM_ROW){ 
      fact = input.nextLine(); 
      foodArray [numberOfLines++] = fact.split(","); 
     } 

질문 하나 : 정적 클래스 변수로 모든 변수를 선언하기위한 특정 목적이 있습니까? 그들 중 대부분은 메서드 내부의 지역 변수로 적합합니다. numberOfLines?

+0

나는 배열을 얻을 때 시트 셀을 엑셀로 잡을 때 나는 이것을 한꺼번에 던지고 있었다. –

+0

@FredV : OK. 이 방법이 효과가 있습니까? 또한'split()'메서드를 사용하지 않는 이유는 무엇입니까? –

+0

@FredV : 당신이 이미 눈치 챘을 때 while 조건을 num_row 정의보다 많은 행을 읽지 않는지 확인하기 위해 while 조건을 while (factFile.hasNextLine() && numberOfLines

0

이 방법을 사용할 수 있습니다. String [][] foodArray = csvreadString(filename); 실제로 파일을 두 번 읽지 만 데이터를 읽지 않고 CSV 차원을 가져 오는 방법을 알지 못합니다. 배열을 초기화하려면 차원이 필요합니다.이 방법은 내가 시도한 다른 방법과 비교할 때 매우 빠릅니다.

static public class PairInt { 

     int rows = 0; 
     int columns = 0; 
    } 
    static PairInt getCsvSize(String filename) throws Throwable { 
     PairInt csvSize = new PairInt(); 
     BufferedReader reader = new BufferedReader(new FileReader(new File(filename))); 
     String line; 
     while ((line = reader.readLine()) != null) { 
      if (csvSize.columns == 0) { 
       csvSize.columns = line.split(",").length; 
      } 
      csvSize.rows++; 
     } 
     reader.close(); 
     return csvSize; 
    } 
    static String[][] csvreadString(String filename) throws Throwable { 
     PairInt csvSize = getCsvSize(filename); 
     String[][] data = new String[csvSize.rows][csvSize.columns]; 
     BufferedReader reader = new BufferedReader(new FileReader(new File(filename))); 
     for (int i = 0; i < csvSize.rows; i++) { 
      data[i] = reader.readLine().split(","); 
     } 
     return data; 
    }