BufferedWriter прекращает запись

Я пытаюсь переписать этот словарь: Dictionary.txt отсортирован по длине, а не по алфавиту. У меня есть следующий код (внутри main(String[] args)):

    BufferedReader read = new BufferedReader(new FileReader(new File(DIC_READ_PATH)));
    BufferedWriter write= new BufferedWriter(new FileWriter(DIC_WRITE_PATH),1);
    ArrayList<String> toWrite = new ArrayList<String>();
    for (int a = read.read(); a != -1; a = read.read()){
        char c = (char) a;
        toWrite.add("" + c + read.readLine());
    }
    read.close();
    Collections.sort(toWrite, new MyComparator());
    for (int a = 0; a <= 70000; a += 10000){
        write.write(toWrite.subList(a, a + 10000).toString().replaceAll("[\\[,\\]]", "").replaceAll(" ", "\n"));
        write.flush();
    }

    write.write(toWrite.subList(80000, toWrite.size()).toString().replaceAll("[\\[,\\]]", "").replaceAll(" ", "\n"));
    write.close();

Мой Компаратор:

public class MyComparator implements Comparator<String> {
@Override
    public int compare(String arg0, String arg1) {
    // TODO Auto-generated method stub
        if (arg0.length() == arg1.length()){
            return arg0.compareTo(arg1); 
        } 
        return arg0.length() < arg1.length() ? -1 : +1;
    }
}

Он отлично сортирует Arraylist, но когда я пишу строки, он не записывает 8 слов. Я попытался изменить буфер в BufferedWriter и обнаружил, что меньшие буферы помогают, поэтому я установил буфер равным 1. Я нашел это: Buffered Writer Java Limit / Issues и пытался сбрасывать каждый раз, когда я пишу, и закрывал в конце (после этого даже менялся буфер). Я все еще получаю 80360 слов вместо 80368. Почему он не записывает полный список слов? Должен ли я использовать другой BufferedWriter? Если да, то как я могу использовать его без перезаписи того, что уже написано?


person Justin    schedule 01.04.2013    source источник


Ответы (2)


вы используете случайные символы ваших входных данных:

for (int a = read.read(); a != -1; a = read.read()){

не смешивайте вызовы read() и readLine(). просто используйте readLine() и проверьте значение null.

Кроме того, чтобы записать свои результаты, не используйте импл List.toString и неприятные замены регулярных выражений, просто переберите список и напишите одно слово, за которым следует новая строка.

person jtahlborn    schedule 01.04.2013
comment
никакие символы не потребляются (a преобразуется в char), но это может быть хорошей идеей. - person Justin; 01.04.2013
comment
Я согласен, что это плохая практика, но imho это другая проблема. Настоящая проблема недостающих 8 — это отсутствие новых строк. - person Gábor Bakos; 01.04.2013
comment
@GáborBakos Бакос О. Спасибо - person Justin; 01.04.2013
comment
@gangqinlaohu - да, персонажи расходуются. в ваших словах, вероятно, отсутствуют первые символы. - person jtahlborn; 02.04.2013
comment
@GáborBakos - да, но простой просмотр списка также решит проблему. - person jtahlborn; 02.04.2013
comment
@jtahlborn сразу после for(int a = read.read(); a != -1; a = read.read()){ идет char c = (char) a;, а в ArrayList добавляется строка c + read.readLine(). Поскольку a преобразуется в char, который затем помещается в строку, никакие символы не теряются. Я сделал это таким образом, чтобы я мог что-то сделать, если первый символ является каким-то символом. - person Justin; 02.04.2013
comment
@gangqinlaohu - ах, пропустил ту часть, где вы снова добавили этот символ. все же лучше не смешивать read() и readLine(). - person jtahlborn; 02.04.2013
comment
@jtahlborn единственная причина, по которой я это делаю, заключается в том, что я могу вызвать что-то, если первый символ в строке что-то, но я должен сделать это только с readLine(), если меня это не волнует. - person Justin; 02.04.2013
comment
Было ли это действительно причиной проблемы? Почему это привело к отсутствию 8 слов? (Я предположил, что количество слов для записи было проверено на каком-то этапе разработки.) - person Gábor Bakos; 02.04.2013

Я думаю, что проблема здесь:

 for (int a = 0; a <= 70000; a += 10000){
        write.write(toWrite.subList(a, a + 10000).toString().replaceAll("[\\[,\\]]", "").replaceAll(" ", "\n"));
        write.flush();
    }

Вы должны написать.write("\n"); перед смывом.

person Gábor Bakos    schedule 01.04.2013
comment
Если вы посмотрите в конец, каждый ' ' заменяется на '\n', поэтому write.write(\n) не требуется. - person Justin; 01.04.2013
comment
Но места в конце не будет. ;) Разве не интересно, что там ровно 8 итераций? - person Gábor Bakos; 01.04.2013