0

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

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

public static void main(String[] args) throws Exception { 

    BufferedReader r1 = new BufferedReader(new FileReader("foo.txt")); 
    BufferedReader r2 = new BufferedReader(new InputStreamReader(new FileInputStream("foo.txt"))); 
    InputStreamReader r3 = new InputStreamReader(new BufferedInputStream(new FileInputStream("foo.txt"))); 
} 

r1 и r2 в значительной степени то же самое, так как FileReader наследуется от InputStreamReader и практически ставит InputStream в это базовый класс. Буферизация в этом случае будет выполняться на уровне символов, после того как байты будут декодированы в текст.

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

Mu вопрос, есть ли какая-либо важная разница, любые ошибки между этими случаями? Есть ли край, где один вариант будет лучше, чем другой?

ответ

1

Реализация FileReader:

public class FileReader extends InputStreamReader { 
    public FileReader(String fileName) throws FileNotFoundException { 
     super(new FileInputStream(fileName)); 
    } 
} 

Итак, вы видите, первые две строки в результате точно такой же цепи.

Третий вариант не подходит для работы. InputStreamReader должен преобразовывать кодировку символов из byte поток в char поток, который медленный на байтовом уровне, но быстрее в блоках.

См Javadoc из InputStreamReader:

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

Для максимальной эффективности рассмотрите возможность упаковки InputStreamReader в BufferedReader. Например:

BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); 

Go с опциями 1. Это короче, чем вариант 2, и делает то же самое, и вариант 3 не является хорошим выбором.

Смежные вопросы