2010-08-13 2 views
2

나는 여러 줄 탭 구분 파일을 취하고 해당 파일의 내용을 문자열 배열의 arraylist로 반환하려고합니다. 각 줄은 String []이고, 그러한 각 String []은 arraylist의 한 요소이다). 내 문제는 출력이 맞는지 여부를 알 수 없다는 것입니다. 각 arraylist 요소와 String [] 요소는 arraylist에 저장되어 인쇄되었으므로 해당 인쇄물은 올바르게 보입니다. 그러나 arraylist가 반환 된 후 String []을 인쇄하면 파일의 마지막 줄의 내용 만있는 것처럼 보입니다. FileReader 또는 BufferedReader에 대해 내가 모르는 것이 아닌지 의심 스럽다. 어쨋든, 여기에 코드는 다음과 같습니다BufferedReader는 파일의 마지막 줄만 읽는 것 같다

public class DataParsingTest { 

    static File AAPLDailyFile = new File("./textFilesForMethodTests/dataParsingPractice2.tsv"); 

    public static void main(String[] args) throws FileNotFoundException, IOException { 
     ArrayList<String[]> stringArrayList = fileToStringArray(AAPLDailyFile); 
     System.out.println("stringArray.size() = " + stringArrayList.size()); 
     System.out.println(stringArrayList.get(0)[0]); 

     for (int i = 0; i < stringArrayList.size(); i++) { 
      for (int j = 0; j < stringArrayList.get(i).length; j++) { 
       System.out.println("index of arraylist is " + i + " and element at index " + j + " of that array is " + stringArrayList.get(i)[j]); 
      } 
     } 
    } 

    public static ArrayList<String[]> fileToStringArray(File file) throws FileNotFoundException, IOException { 
     ArrayList<String[]> arrayListOfStringArrays = new ArrayList<String[]>(); 
     FileReader fileReader = new FileReader(file); 
     BufferedReader bufferedReader = new BufferedReader(fileReader); 
     int nextChar = 0; 
     int noOfTokens = 1; // because the first token doesn't have a tab or newline before it 
     int startIndex = 0, endIndex = 0, tokenIndex = 0; 
     String toRead = ""; 
     toRead = bufferedReader.readLine(); 
     for (int i = 0; i < toRead.length(); i++) { 
      if (toRead.charAt(i) == '\t') { 
       noOfTokens++; 
      } 
     } 
     System.out.println("noOfTokens = " + noOfTokens); 
     bufferedReader.close(); 
     fileReader.close(); 
     String[] productString = new String[noOfTokens]; 
     startIndex = 0; 
     endIndex = 0; 
     tokenIndex = 0; 
     FileReader fileReader2 = new FileReader(file); 
     BufferedReader bufferedReader2 = new BufferedReader(fileReader2); 

     tokenIndex = 0; 
     int count = 1; 
     while ((toRead = bufferedReader2.readLine()) != null) { 
      System.out.println("toRead = " + toRead); 
      startIndex = -1; // [L - so that the first time an array element is assigned, it's upped to 0] 
      endIndex = 0; 
      tokenIndex = 0; 
      while (true) { 
       endIndex = toRead.indexOf("\t", startIndex + 1); 
       if (endIndex == -1) { 
        productString[tokenIndex] = toRead.substring(startIndex + 1); 
        System.out.println("tokenIndex = " + tokenIndex); 
        System.out.println("productString[" + tokenIndex + "] = " + productString[tokenIndex]); 
        tokenIndex++; 
        count++; 
        arrayListOfStringArrays.add(productString); 
        System.out.println("just added an array to the list. the first element is " + productString[0]); 
        break; 
       } 
       productString[tokenIndex] = toRead.substring(startIndex + 1, endIndex); 
       System.out.println("tokenIndex = " + tokenIndex); 
       System.out.println("productString[" + tokenIndex + "] = " + productString[tokenIndex]); 
       startIndex = endIndex; 
       tokenIndex++; 
       count++; 
      } 
     } 
     fileReader2.close(); 
     bufferedReader2.close(); 
     return arrayListOfStringArrays; 
    } 
} 

입력 파일은 다음과 같습니다

1 2 
3 4 
5 6 

출력은 다음과 같습니다

noOfTokens = 2 
toRead = 1  2 
tokenIndex = 0 
productString[0] = 1 
tokenIndex = 1 
productString[1] = 2 
just added an array to the list. the first element is 1 
toRead = 3  4 
tokenIndex = 0 
productString[0] = 3 
tokenIndex = 1 
productString[1] = 4 
just added an array to the list. the first element is 3 
toRead = 5  6 
tokenIndex = 0 
productString[0] = 5 
tokenIndex = 1 
productString[1] = 6 
just added an array to the list. the first element is 5 
stringArray.size() = 3 
5 // from here on up, it looks like the method works correctly 
index of arraylist is 0 and element at index 0 of that array is 5 
index of arraylist is 0 and element at index 1 of that array is 6 
index of arraylist is 1 and element at index 0 of that array is 5 
index of arraylist is 1 and element at index 1 of that array is 6 
index of arraylist is 2 and element at index 0 of that array is 5 
index of arraylist is 2 and element at index 1 of that array is 6 //these 6 lines only reflect the last line of the input file. 

감사 달러를!

답변

8

문자열 배열을 하나만 만들고 모든 행에 다시 사용하고 있습니다. 따라서 ArrayList에는 동일한 개체에 대한 여러 참조가 포함되어 있습니다. 배열 사본을 ArrayList에 추가하지 않고 arrayListOfStringArrays.add(productString);으로 전화 할 때 참조을 추가하는 것임을 이해해야합니다. (productString의 값은 참조하지 배열 자체이다.)

그냥이 이동할 다음 while 루프

String[] productString = new String[noOfTokens]; 

를 모두 잘해야한다. (이와 관련하여 어쨌든 finally 블록의 파일 핸들을 닫아야합니다.)

+0

내 upvote 광산 경우 upvote거야! ': P' – jjnguy

+0

* (그러나, 나는 더 이상 upvotes가 정말로 당신을 오늘 도와주지 않을 것이라고 확신합니다) * – jjnguy

+2

Duh! 그것은 항상 나를 얻는 바보 같은 물건입니다. 좋은 설명. 이제 완벽하게 작동합니다. 또한 그 점을 알게 된 사고에 대해 설명해 주시겠습니까? –

2

너무 많은 코드로 처리 할 수 ​​있습니다. 이 변경된 fileToStringArray 메소드를 사용해보십시오.

public static ArrayList<String[]> fileToStringArray(File file) throws FileNotFoundException, IOException { 
    ArrayList<String[]> returnVal = new ArrayList<String[]>(); 
    // Scanner is a nifty utility for reading Files 
    Scanner fIn = new Scanner(file); 
    // keep reading while the Scanner has lines to process 
    while (fIn.hasNextLine()) { 
     // take the next line of the file, and split it up by each tab 
     // and add that String[] to the list 
     returnVal.add(fIn.nextLine().split("\t", -1)); 
    } 
    return returnVal; 
} 
+0

고마워요! 저는 Java로 시작한 적이 있으며 스캐너를 사용한 적이 없습니다. 정말로 API를 더 잘 알아야합니다. 이것은 엄청나게 효율적입니다. –

+0

@Anita, 글쎄요, Stack Overflow에 와서 많은 것을 배울 수 있습니다. 또한 String.split()을 참조해야합니다. 너무 유용합니다. – jjnguy

+0

아, 스플리터가 연습용이었습니다 :) 그렇다면 스캐너가 훨씬 더 다양한 용도로 사용되는 경우 FileReader를 사용해야하는 이유는 무엇입니까? –