DataInputStream и readLine () с UTF8 - PullRequest
1 голос
/ 16 июня 2011

У меня возникли проблемы с отправкой строки UTF8 из сокета c в сокет Java. Следующий метод отлично работает:

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
main.title = in.readLine();

но тогда мне нужен метод int java.io.InputStream.read(byte[] b, int offset, int length), который не существует для BufferedReader. Итак, я попытался взять DataInputStream

DataInputStream in2 = new DataInputStream(socket.getInputStream());

но все, что он читает, это просто мусор.

Затем я попытался использовать метод readLine() из DataInputStream, но это не дает мне правильную строку UTF8.

Вы видите мою дилемму. Разве я не могу использовать два считывателя для одного InputStream? Или я могу преобразовать результат DataInputStream.readLine() и преобразовать его в UTF8?

Спасибо, Martin

Ответы [ 4 ]

7 голосов
/ 16 июня 2011

Мы знаем из конструкции кодировки UTF-8 , что единственным значением 0x0A является только LINE FEED ('\n'). Таким образом, вы можете читать, пока не нажмете:

  /** Reads UTF-8 character data; lines are terminated with '\n' */
  public static String readLine(InputStream in) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    while (true) {
      int b = in.read();
      if (b < 0) {
        throw new IOException("Data truncated");
      }
      if (b == 0x0A) {
        break;
      }
      buffer.write(b);
    }
    return new String(buffer.toByteArray(), "UTF-8");
  }

Я предполагаю, что ваш протокол использует \n в качестве ограничителя строки. Если это не так - обычно полезно указать ограничения, в которые вы пишете.

3 голосов
/ 04 июля 2011

Делать НЕ использовать BufferedReader и DataInputStream на одном InputStream !! Я сделал это и провел дни, пытаясь выяснить, почему мой код сломался. BufferedReader может читать больше, чем вы извлекаете из него, в его буфер, что приводит к ситуации, когда данные, которые я должен был прочитать с DataInputStream, находятся "в BufferedReader". Это привело к потере данных, в результате чего моя программа «зависла» в ожидании ее поступления.

1 голос
/ 16 июня 2011

Правильно ли я понимаю, что вы отправляете как текстовые, так и двоичные данные в один и тот же сокет, в один и тот же "разговор"?Не должно быть проблем с созданием двух считывателей для одного и того же входного потока.Проблема в том, чтобы знать, когда (и сколько) читать читателю.Они оба будут потреблять (и продвигать) базовый поток при чтении из них, поскольку у вас смешанные типы данных.Вы можете просто прочитать поток как байты, а затем явно преобразовать байты в вашем коде (новая строка (байты, "UTF-8") и т. Д.).Или вы можете разделить ваше сообщение на два разных сокета.

1 голос
/ 16 июня 2011

Я считаю, что вы не должны не соответствовать BufferedReader и DataInputStream здесь.DataInputStream также имеет readLine(), так что используйте его.И еще один комментарий.Я не уверен, что это проблема, но избегайте множественных вызовов socket.getInputStream().Сделайте это один раз, а затем оберните его, как хотите, используя другие потоки и программы чтения.

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