Можно ли читать из файла, используя только FileReader?

Я знаю, что правильный подход

BufferedReader br = new BufferedReader(FileReader(file));

но я проверил в Java API методы класса FileReader, и у него есть метод read(), который возвращает прочитанный символ. Но это не работает для меня. Я читаю файл, содержащий эту строку текста: «Я читаю файл» и печатаю его на экране, но когда я запускаю программу, она печатает эквивалентный код ASCII для каждого символа.

Это мой код:

String lectura = "";
try{
    lectura = String.valueOf(fr.read());
} catch(IOException ioex){
    ioex.printStackTrace();
}

while((Integer.parseInt(lectura)) != -1){
    System.out.print(lectura);
    try{
        lectura = String.valueOf(fr.read());
    } catch(IOException ioex){
        ioex.printStackTrace();
    }
}

person Aikanáro    schedule 27.02.2012    source источник


Ответы (3)


Происходит вот что -

fr.read() возвращает целое число, а не символ, хотя возвращаемое целое число является эквивалентным кодом ASCII для этого символа.

Когда вы вызываете String.valueOf() для этого целого числа, вызывается метод String.valueOf(int i) вместо метода String.valueOf(char c), который вы ожидаете вызвать, и поэтому он возвращает значение ASCII. как строку, а не символьное значение как строку.

Поэтому вместо этого попробуйте

    lectura = String.valueOf( (char) (fr.read()) );
person CodeBlue    schedule 27.02.2012
comment
Почти -- целые числа не являются значениями ASCII, FileReader использует кодировку платформы по умолчанию. - person Daniel Lubarov; 27.02.2012
comment
Ну, если бы файл был записан обычными 7-битными символами ASCII, разницы бы не было. Но если текстовый редактор записал его, например, с помощью latin1, fr.read() вернет некоторые целые числа, которые не являются допустимыми кодами ASCII. (Или он может вернуть бессмыслицу, если Charset.defaultCharset() — это что-то вроде UTF-8.) - person Daniel Lubarov; 27.02.2012
comment
Хорошо, но теперь у меня проблемы с остановкой цикла чтения, потому что я делаю это с while(Integer.parseInt(lectura) != -1) и получаю NumberFormatException, когда значение lectura не является числом, и это происходит только тогда, когда достигнут конец файла. - person Aikanáro; 27.02.2012
comment
@Aikanáro, вам нужно проверить, что fr.read() не вернул -1, и если это так, остановитесь, не меняя lectura. - person Daniel Lubarov; 27.02.2012
comment
Вот что я сделал: ‹br/› while(true){if(fr.read() == -1) break; else lectura = String.valueOf((char)fr.read())} - person Aikanáro; 27.02.2012
comment
Теперь печатает предложение, но не то, что я написал в файле. Не имеет смысла, что он печатает. Вроде алеаторные персонажи. - person Aikanáro; 27.02.2012
comment
@Aikanáro проблема в том, что когда вы вызываете fr.read и проверяете, равен ли он -1, этот символ теперь прочитан, и вызов read, результат которого вы используете, получит следующий символ. Просто вызовите read один раз, сохраните результат в переменной и используйте эту переменную как в тесте EOF, так и когда вы фактически используете значение. - person Daniel Lubarov; 27.02.2012

Это ожидаемое поведение, текст хранится в виде байтов, и каждый байт имеет значение ASCII символа. Вы можете собрать эти байты в массив байтов, а затем использовать новую строку (массив); преобразовать их в строку. Или вы можете преобразовать в char для преобразования отдельных символов.

person Usman Ismail    schedule 27.02.2012
comment
InputStream читает байты, Reader читает символы. (Что сбивает с толку, так это то, что оба они закодированы как целые числа.) Вот почему InputStreamReader нуждается в Charset; было бы неправильно просто рассматривать байты как символы, хотя это сработает для ASCII. Вы бы не хотели создавать массив байтов из Reader и вызывать new String(byte[]); вы бы построили массив символов и вызвали new String(char[]). - person Daniel Lubarov; 27.02.2012

FileReader read возвращает int. Вам просто нужно привести это к char.

Причина, по которой read Reader не просто возвращает char, заключается в том, что использование int позволяет использовать -1 для представления конца файла.

person Daniel Lubarov    schedule 27.02.2012