2010-08-13 39 views
2

J'essaye d'écrire une méthode pour prendre un fichier multiligne délimité par des tabulations et retourner le contenu de ce fichier comme une liste de tableaux de chaînes (chaque ligne est une chaîne [], et chacun de ces String [] est un élément d'une liste de choix). Mon problème est, je ne peux pas dire si la sortie est correcte ou non. J'ai imprimé chaque élément arraylist et élément String [] comme ils sont enregistrés dans l'arraylist, et ces impressions semblent correctes. Mais après que l'arraylist est retourné et que j'imprime le String [], ils semblent avoir seulement le contenu de la toute dernière ligne du fichier. Je soupçonne que ce soit quelque chose à propos de FileReader ou de BufferedReader que je ne connais pas. Anyhoo, voici le code:BufferedReader ne semble lire que la dernière ligne du fichier

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

Le fichier d'entrée est:

1 2 
3 4 
5 6 

La sortie est:

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. 

Merci un mil!

Répondre

8

Vous créez uniquement un groupe de chaînes unique et vous le réutilisez pour toutes les lignes. Donc, votre ArrayList contient juste plusieurs références au même objet. Vous devez comprendre que lorsque vous appelez arrayListOfStringArrays.add(productString); cela n'ajoute pas une copie du tableau au ArrayList - c'est juste d'ajouter une référence . (La valeur de productString est juste une référence, pas le tableau lui-même.)

Il suffit de déplacer ceci:

String[] productString = new String[noOfTokens]; 

dans la boucle while, et tout devrait bien. (À cet égard, de toute façon, vous devriez également fermer vos poignées de fichier dans finally blocs.)

+0

Je vais upvoter le vôtre si vous faites miens le mien! ': P' – jjnguy

+0

* (Cependant, je suis sûr que d'autres upvotes ne vous aideront pas vraiment aujourd'hui) * – jjnguy

+2

Duh! C'est toujours un truc idiot comme ça qui m'atteint. Bonne explication. Cela fonctionne parfaitement maintenant. Aussi, pouvez-vous expliquer la pensée qui vous a amené à repérer cela? –

2

Cela ressemble à trop de code pour moi de traiter. Essayez cette méthode modifiée 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

Merci! Je viens juste de commencer avec Java et je n'ai jamais utilisé de scanner. Vraiment devrait mieux connaître l'API. C'est ridiculement plus efficace. –

+0

@Anita, eh bien, vous pouvez apprendre beaucoup en venant à Stack Overflow. Vous devriez aussi chercher String.split() c'est super utile aussi! – jjnguy

+0

Oh, le séparateur était censé être un exercice :) Alors, pourquoi quelqu'un utiliserait-il FileReader si Scanner semblait tellement plus polyvalent? –