Чтение всего содержимого Java BufferedReader, включая символы завершения строки
Я пишу TCP-клиент, который получает двоичные данные и отправляет их на устройство. Проблема возникает, когда я использую BufferedReader, чтобы прочитать то, что он получил.
Я чрезвычайно озадачен, обнаружив, что нет никакого метода, доступного для чтения всех данных. readLine()
метод, который используют все, обнаруживает оба \n
а также \r
символы как символы окончания строки, поэтому я не могу получить данные и конкатить строки, потому что я не знаю, какой символ был символом конца строки. Я тоже не могу использовать read(buf, offset, num)
потому что он не возвращает количество прочитанных байтов. Если я читаю это побайтно, используя read()
метод, это стало бы ужасно медленно. Пожалуйста, кто-нибудь, скажите мне, каково решение, этот API кажется мне довольно глупым!
Ну, во-первых, спасибо всем. Я думаю, что основная проблема была в том, что я прочитал tutorialspoint вместо документации по Java. Но простите меня за это, так как я живу в Иране, а Oracle не дает нам доступа к документации по какой бы то ни было причине. В любом случае, спасибо за терпение и полезные ответы.
4 ответа
Это более чем вероятно проблема XY.
Начало вашего вопроса гласит:
Я пишу TCP-клиент, который получает двоичные данные и отправляет их на устройство. Проблема возникает, когда я использую BufferedReader, чтобы прочитать то, что он получил.
Это двоичные данные; не используйте Reader
начать с! Reader оборачивает InputStream, используя Charset, и выдает поток char
с не byte
s. Смотрите, среди других источников, здесь для более подробной информации.
Следующий:
Я очень озадачен, обнаружив, что нет никакого метода, доступного для чтения всех данных
С разумом. Невозможно сказать, насколько большими могут быть данные, и в результате такой метод будет чреват проблемами, если получаемые вами данные слишком велики.
Итак, теперь, используя Reader
что вы действительно должны сделать, это:
- читать некоторые двоичные данные из
Socket
; - скопируйте эти данные в другой источник.
Решений для этого много; Вот одно решение, которое не требует ничего, кроме стандартного JDK (7+):
final byte[] buf = new byte[8192]; // or other
try (
final InputStream in = theSocket.getInputStream();
final OutputStream out = whatever();
) {
int nrBytes;
while ((nrBytes = in.read(buf)) != -1)
out.write(buf, 0, nrBytes);
}
Оберните этот код в метод или что-то и т. Д.
Я чрезвычайно озадачен, обнаружив, что нет никакого метода, доступного для чтения всех данных.
Есть три.
Метод readLine(), который используют все, обнаруживает символы \n и \r как символы окончания строки, поэтому я не могу получить данные и выполнить конкатенацию строк, потому что я не знаю, какой символ был символом конца строки.
Правильный. Документально подтверждено подавление ограничителя строки.
Я также не могу использовать read(buf, offset, num), потому что он не возвращает количество прочитанных байтов.
Возвращает количество прочитанных символов.
Если бы я читал его побайтово, используя метод read(), он стал бы ужасно медленным.
Это означает, что символ за символом, а не побайтно, но вы ошибаетесь в производительности. Это буферизовано.
Пожалуйста, кто-нибудь, скажите мне, каково решение
Вы не должны использовать Reader
для двоичных данных в первую очередь. Я могу только предложить вам перечитать Javadoc для:
BufferedInputStream.read() throws IOException;
BufferedInputStream.read(byte[]) throws IOException;
BufferedInputStream.read(byte[], int, int) throws IOException;
Последние два возвращают количество прочитанных байтов или -1 в конце потока.
этот API кажется мне довольно глупым!
Без комментариев.
Во-первых, каждый, кто читает данные, должен планировать \ n, \ r, \ r \ n в качестве возможных последовательностей, за исключением случаев синтаксического анализа заголовков HTTP, которые должны быть разделены \r\n. Вы можете легко читать построчно и выводить любой разделитель строк, который вам нравится.
Во-вторых, метод read возвращает количество символов, которые он прочитал в char[], так что он работает абсолютно правильно, если вы хотите прочитать блок символов и выполнить свой собственный анализ строки и вывод.
Лучшее, что я могу порекомендовать, - это использовать BufferedReader.read() и выполнять итерацию по каждому символу в файле. Что-то вроде этого:
String filename = ...
br = new BufferedReader( new FileInputStream(filename));
while (true) {
String l = "";
Char c = " ";
while (true){
c = br.read();
if not c == "\n"{
// do stuff, not sure what you want with the endl encoding
// break to return endl-free line
}
if not c == "\r"{
// do stuff, not sure what you want with the endl encoding
// break to return endl-free line
Char ctwo = ' '
ctwo = br.read();
if ctwo == "\n"{
// do extra stuff since you know that you've got a \r\n
}
}
else{
l = l + c;
}
if (l == null) break;
...
l = "";
}
ранее ответил @ arrdem