ReadableByteChannel
(たとえば、FileChannel
)を文字列にする必要があります。私はラップトップが収集されたときにチャネルを閉じたくないので、Channels.newReader()
またはChannels.newInputStream()
でチャネルをラップすることでこれを行うことはできません。私はまたすべてのバイトを中間に保存したくありませんByteBuffer
。nioチャンネル全体を文字列に読み取る
ループ内の入力を読み込み、CharsetDecoder.decode(ByteBuffer, CharBuffer, boolean)
を呼び出したかったのですが、フルになったときにCharBufferを再割り当てしないという問題がありました。そのためのソリューションが複雑すぎになります
public static CharBuffer readAll(final ReadableByteChannel ch, final Charset cs)
throws IOException {
final ByteBuffer bb = ByteBuffer.allocate(3);
CharBuffer cb = null;
final CharsetDecoder dec = cs.newDecoder();
while (ch.read(bb) > 0) {
bb.flip();
cb = mydecode(dec, cb, bb);
bb.clear();
}
bb.flip();
dec.decode(bb, cb, true);
cb.flip();
return cb;
}
// modified CharsetDecoder.decode(ByteBuffer)
private static CharBuffer mydecode(final CharsetDecoder dec, CharBuffer out, final ByteBuffer in)
throws CharacterCodingException {
int n = (int) (in.remaining() * dec.averageCharsPerByte());
if (out == null) {
out = CharBuffer.allocate(n);
}
if ((n == 0) && (in.remaining() == 0)) {
return out;
}
// dec.reset();
for (;;) {
final CoderResult cr = in.hasRemaining() ? dec.decode(in, out
// , true
, false) : CoderResult.UNDERFLOW;
if (cr.isUnderflow()) {
// cr = dec.flush(out);
}
if (cr.isUnderflow()) {
break;
}
if (cr.isOverflow()) {
n = 2 * n + 1; // Ensure progress; n might be 0!
final CharBuffer o = CharBuffer.allocate(n);
out.flip();
o.put(out);
out = o;
continue;
}
cr.throwException();
}
// out.flip();
return out;
}
あなたがしようとしているものを得ることができませんでした。しかし、2つのイデアリアが役立つことがあります。 1.パラレルデコードされたコンテンツをStringBuilderに格納し、読み込み後にCharBufferにラップします。 2.ファイルサイズに基づいてより大きなCharBufferを割り当て、読み込み後にトリミングします。 – fhofmann