Почему "обвязка" CharBuffer зависает? - PullRequest
0 голосов
/ 24 сентября 2008

Почему зависает следующий метод?

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
    }
}

Ответы [ 3 ]

1 голос
/ 24 сентября 2008

Отвечая на мой собственный вопрос: вы должны позвонить buf.clear() между read с. Предположительно, read зависает, потому что буфер заполнен. Правильный код

public void pipe(Reader in, Writer out) {
    CharBuffer buf = CharBuffer.allocate(DEFAULT_BUFFER_SIZE);
    while( in.read(buf) >= 0 ) {
      out.append(buf.flip());
      buf.clear();
    }
}
0 голосов
/ 09 марта 2012

CharBuffers не работают с Readers и Writers так четко, как вы могли бы ожидать. В частности, нет метода Writer.append(CharBuffer buf). Метод, вызываемый фрагментом вопроса, - Writer.append(CharSequence seq), который просто вызывает seq.toString(). Метод CharBuffer.toString() возвращает строковое значение буфера, но не истощает буфер. Последующий вызов Reader.read(CharBuffer buf) получает уже заполненный буфер и, следовательно, возвращает 0, заставляя цикл продолжаться бесконечно.

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

Как это ни раздражает, я бы порекомендовал реализацию char [] хотя бы потому, что решение CharBuffer приводит к созданию как минимум двух новых char [] при каждом прохождении цикла.

public void pipe(Reader in, Writer out) throws IOException {
    char[] buf = new char[DEFAULT_BUFFER_SIZE];
    int count = in.read(buf);
    while( count >= 0 ) {
        out.write(buf, 0, count);
        count = in.read(buf);
    }
}

Я бы рекомендовал использовать это только в том случае, если вам необходимо поддерживать преобразование между двумя кодировками символов, в противном случае реализация ByteBuffer / Channel или byte [] / IOStream будет предпочтительнее, даже если вы передаете символы.

0 голосов
/ 24 сентября 2008

Я бы предположил, что это тупик. In.read (buf) блокирует CharBuffer и предотвращает вызов out.append (buf).

Это предполагает, что CharBuffer использует блокировки (некоторого вида) в реализации. Что API говорит о классе CharBuffer?

Редактировать: Извините, какое-то короткое замыкание в моем мозгу ... Я перепутал это с чем-то другим.

...