代码之家  ›  专栏  ›  技术社区  ›  Bad Request

BufferedReader似乎只读取文件的最后一行

  •  2
  • Bad Request  · 技术社区  · 14 年前

    我正在尝试编写一个方法来获取一个多行制表符分隔的文件,并将该文件的内容作为字符串数组的arraylist返回(每行都是一个字符串[],而每一个这样的字符串[]都是arraylist的一个元素)。我的问题是,我不知道输出是否正确。我已经打印了每个arraylist元素和String[]元素,因为它们保存到arraylist中,这些打印看起来是正确的。但是在返回arraylist并在其中打印字符串[]之后,它们似乎只包含文件最后一行的内容。我怀疑可能是关于FileReader或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.
    

    非常感谢!

    2 回复  |  直到 14 年前
        1
  •  8
  •   Jon Skeet    14 年前

    你只是在创造一个 字符串数组,并对所有行重复使用该数组。所以你的 ArrayList 只包含对同一对象的多个引用。你打电话的时候要明白这一点 arrayListOfStringArrays.add(productString); 这并不是将数组的副本添加到 -只是增加了一个 参考 . (价值 productString 只是一个引用,而不是数组本身。)

    移动这个:

    String[] productString = new String[noOfTokens];
    

    进入 while finally 方块。)

        2
  •  2
  •   jjnguy Julien Chastang    14 年前

    看起来代码太多了,我无法处理。试试这个 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;
    }