BufferedReader возвращает null, даже если в файле есть текст

BufferedReader rea = new BufferedReader(new FileReader("points.txt"));
BufferedWriter writ = new BufferedWriter(new FileWriter("points.txt"));

ArrayList<String> top = new ArrayList<String>();

// checking if file is empty, so it enters imaginary players and scores
// if it is.
if (rea.readLine() == null) {
    for (int i = 1; i < 6; i++) {
        writ.write("Player" + i + "\t\t" + "99:99");
        writ.newLine();
    }
}
while ((readthis = rea.readLine()) != null) {
    top.add(readthis);
}

Итак, что происходит, так это то, что, несмотря на то, что в моем файле «points.txt» уже есть несколько выдуманных игроков, он все равно возвращает true в этом первом предложении if, поэтому новые игроки печатаются в файле. Но проблема в том, что когда я пытаюсь прочитать файл в предложении while, он даже не проходит через него. Я проверил с помощью System.out.println() и обнаружил, что он возвращает значение null. Как он может вернуть null, даже если я видел, как он заполняет новые данные? Что я делаю не так? Я борюсь с этой проблемой уже около полутора часов, перепробовал все, что знаю. Любая помощь очень ценится.


person user3204315    schedule 22.01.2014    source источник
comment
в первом цикле вы должны сбросить свой writer   -  person nachokk    schedule 22.01.2014
comment
Это совет: Use List‹String› top = new ArrayList‹String›(); вместо ArrayList‹String› top = new ArrayList‹String›();   -  person ashokramcse    schedule 22.01.2014
comment
@ashokramcse также использует <> алмазный вывод, если он использует java 7 или выше!   -  person nachokk    schedule 22.01.2014


Ответы (3)


Пожалуйста, поймите, что одновременное чтение и запись в файл с помощью BufferedReader/Writer не очень хорошая идея.

При использовании буферизованного чтения или записи нет гарантии, когда будет выполнено фактическое чтение и запись.

При этом одним из исправлений является установка отметки на считывателе до достижения конца файла, а также закрытие (или, по крайней мере, сброс) выходного потока. Это заставит BufferedWriter фактически записать содержимое в файловую систему и позволит читателю прочитать новое содержимое.

Примечание. Вы можете обнаружить, что в некоторых файловых системах этот подход не работает.

rea.mark(4048); // Set mark at beginning of file    
if (rea.readLine() == null) {
    for (int i = 1; i < 6; i++) {
        writ.write("Player" + i + "\t\t" + "99:99");
        writ.newLine();
    }
    writ.close();
    rea.reset();
}

При этом я думаю, что лучшим подходом было бы проверить длину и существование файла перед попыткой чтения из него. См. образец ниже.

File file = new File("points.txt");

// checking if file is empty, so it enters imaginary players and scores
// if it is.'
if ((!file.exists()) || (file.length() == 0)) {
    try (BufferedWriter writ = new BufferedWriter(new FileWriter(file))) {
        for (int i = 1; i < 6; i++) {
            writ.write("Player" + i + "\t\t" + "99:99");
            writ.newLine();
        }
    }
    // writ is closed by the try()
}
try (BufferedReader rea = new BufferedReader(new FileReader(file))) {
    ArrayList<String> top = new ArrayList<String>();

    String readthis;
    while ((readthis = rea.readLine()) != null) {
        top.add(readthis);
    }
}
// rea is safely closed by the try()

Создание потока помещено в блоки try(), чтобы их можно было безопасно очистить.

Надеюсь, это поможет.

person MrJacqes    schedule 22.01.2014

Используя new BufferedWriter(new FileWriter("points.txt"));, вы переопределяете предыдущее содержимое файла. Если вы хотите добавить новый контент в конец существующего файла, вам нужно использовать конструктор с аргументом boolean append, например

new BufferedWriter(new FileWriter("points.txt"),true);

Также не забудьте сбросить/закрыть ваши программы чтения/записи.

person Pshemo    schedule 22.01.2014
comment
То, что он спрашивает, почему это не читается, даже если он просто пишет в него, и ответ: он не flush/close писателю +1 за указание на это! - person nachokk; 22.01.2014

Этот код

BufferedWriter writ = new BufferedWriter(new FileWriter("points.txt"));

перезаписывает исходный файл.

использовать

BufferedWriter writ = new BufferedWriter(new FileWriter("points.txt"),true);

добавить

person Scary Wombat    schedule 22.01.2014