BufferedReader, кажется, читает только последнюю строку файла - PullRequest
2 голосов
/ 13 августа 2010

Я пытаюсь написать метод, чтобы взять многострочный файл с разделителями табуляции и вернуть содержимое этого файла в виде массива массивов String (каждая строка - это String [], и каждая такая строка [] - это элементArrayList).Моя проблема в том, что я не могу сказать, правильный ли вывод или нет.Я напечатал каждый элемент arraylist и элемент String [], так как они сохранены в arraylist, и эти печати выглядят правильно.Но после того, как массив возвращается, и я печатаю в нем строку [], они, похоже, содержат только самую последнюю строку файла.Я подозреваю, что это может быть что-то о FileReader или BufferedReader, что я не знаю.Anyhoo, вот код:

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 ]

8 голосов
/ 14 августа 2010

Вы только создаете одиночный строковый массив и повторно используете его для всех строк. Таким образом, ваш ArrayList просто содержит несколько ссылок на один и тот же объект. Вы должны понимать, что когда вы вызываете arrayListOfStringArrays.add(productString);, это не добавляет копию массива к ArrayList - это просто добавляет ссылку . (Значение productString - это просто ссылка, а не сам массив.)

Просто переместите это:

String[] productString = new String[noOfTokens];

в цикл while, и все должно быть хорошо. (В любом случае, в этом отношении. Вы также должны закрывать свои файловые дескрипторы в finally блоках.)

2 голосов
/ 14 августа 2010

Это выглядит как слишком много кода для обработки.Попробуйте этот измененный 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;
}
...