Используйте один InputStream в качестве источника для нескольких InputStreams более высокого уровня (например, BufferedReader, DataInputStream) - PullRequest
1 голос
/ 23 октября 2011

Я просто бродил, если это была хорошая или плохая идея:

InputStreamReader in = new InputStreamReader(socket.getInputStream());
BufferedReader reader = new BufferedReader(in);
DataInputStream dis = new DataInputStream(in);

Теперь я хотел бы прочитать из BufferedReader.Если поступит определенная команда (просто строка), я бы хотел продолжить чтение из DataInputStream.

Это работает?Если да, считается ли это хорошей или плохой практикой?

Ответы [ 2 ]

5 голосов
/ 23 октября 2011

(я думаю, ваш пример разбит с точки зрения того, что такое читатель и что такое поток ввода, но я все равно получаю вопрос)

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

Поток ввода сокета, с которым вы работаете, позволит вам прочитать определенный байт только один раз (проверка InputStream.markSupported()).Вы можете обернуть этот входной поток в BufferedInputStream, который эффективно читает несколько байтов вперед, но также добавляет функциональность для выполнения mark() и reset().

Это означает, что любой поток чтения / ввода поверхBufferedInputStream может читать вперед, пометить, пропустить назад и т. д. Но здесь вы должны быть осторожны, чтобы не добавлять еще один слой "буферов" - то есть BufferedReader> InputStreamReader> BufferedInputStream> InputStream.

Таким образом, ответ - да, его можно заставить работать, просто знайте точное поведение каждого компонента (я часто вижу людей, добавляющих BufferedXXX просто для ада).

В вашем примере я бы сделал:

BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
InputStreamReader reader = new InputStreamReader(in, "utf-8"); // consider char encoding
DataInputStream dis = new DataInputStream(in);
2 голосов
/ 23 октября 2011

Это не будет работать.

Буферный читатель читает буферы и анализирует их как строки. Так, если, например, доступно 2 с половиной строки, он, вероятно, переместит маркер потока полезной нагрузки в эту позицию. Теперь вы читаете строку, а затем решаете прочитать длинное значение, используя DataInputStream. Код будет пытаться прочитать это значение с позиции потока полезной нагрузки (после 2,5 строк). Но вы действительно хотели прочитать число после первой строки.

Я думаю, этот пример объясняет также, почему эта идея не является хорошей практикой. Java-потоки реализуют шаблон декоратора (оболочки). Каждый поток добавляет свою собственную функциональность. Попытка обернуть один и тот же «настоящий» поток несколькими обертками выглядит как попытка разорвать эту инкапсуляцию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...