關於 java,nio,bufferedreader,bytebuffer


有沒有一種方法來讀取的ByteBuffer有一個BufferedReader,而無需將其轉換為String優先?我想讀通過一個相當大的 ByteBuffer作為文本行和我想避免它寫入磁盤性能方面的原因。對ByteBuffer的調用toString不起作用生成的字符串太大(它拋出 java.lang.OutOfMemoryError:Java堆空間)。我本來以為會有的API來包裝的ByteBuffer在合適的讀者,但我似乎 無法找到任何合適的。 下面是我做的一個簡短的代碼示例中):

// input stream is from Process getInputStream()
public String read(InputStream istream)
{
 ReadableByteChannel source = Channels.newChannel(istream);
 ByteArrayOutputStream ostream = new ByteArrayOutputStream(bufferSize);
 WritableByteChannel destination = Channels.newChannel(ostream);
 ByteBuffer buffer = ByteBuffer.allocateDirect(writeBufferSize);
 while (source.read(buffer) != -1)
 {
 buffer.flip();
 while (buffer.hasRemaining())
 {
  destination.write(buffer);
 }
 buffer.clear();
 }
 // this data can be up to 150 MB.. won't fit in a String.
 result = ostream.toString();
 source.close();
 destination.close();
 return result;
}
// after the process is run, we call this method with the String
public void readLines(String text)
{
 BufferedReader reader = new BufferedReader(new StringReader(text));
 String line;
 while ((line = reader.readLine()) != null)
 {
 // do stuff with line
 }
}


1. 目前尚不清楚為什么你是一個字節的緩沖區開始。如果你有一個InputStream和你想讀行吧,你為什么不一個InputStreamReader包裹在一個BufferedReader?是什么在獲得NIO涉及的利益? 調用toString()上一個ByteArrayOutputStream聽起來好像即使你有它的空間是一個壞主意:不如把它作為一個字節數組並把它包在一個ByteArrayInputStream然后一個InputStreamReader,如果你真的必須有一個ByteArrayOutputStream。如果你真的想調用toString()在它接受的字符編碼的過載-否則“系統默認的,這可能不是你想要的。 編輯:好了,你真的想NIO。你還在寫一ByteArrayOutputStream最終,所以你最終有一個BAOS與它的數據。如果你想避免讓這些數據的副本,你需要從派生ByteArrayOutputStream例如像這樣:
public class ReadableByteArrayOutputStream extends ByteArrayOutputStream
{
 /**
  * Converts the data in the current stream into a ByteArrayInputStream.
  * The resulting stream wraps the existing byte array directly;
  * further writes to this output stream will result in unpredictable
  * behavior.
  */
 public InputStream toInputStream()
 {
  return new ByteArrayInputStream(array, 0, count);
 }
}
然后 CodeGo.net,您可以創建輸入流,把它包在InputStreamReader,包裹在一個BufferedReader和你離開。 
2. 你NIO,但這里沒有真正的需要。由於喬恩斯基特建議:
public byte[] read(InputStream istream)
{
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 byte[] buffer = new byte[1024]; // Experiment with this value
 int bytesRead;
 while ((bytesRead = istream.read(buffer)) != -1)
 {
 baos.write(buffer, 0, bytesRead);
 }
 return baos.toByteArray();
}

// after the process is run, we call this method with the String
public void readLines(byte[] data)
{
 BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(data)));
 String line;
 while ((line = reader.readLine()) != null)
 {
 // do stuff with line
 }
}

3. 這是一個示例:
public class ByteBufferBackedInputStream extends InputStream {
 ByteBuffer buf;
 public ByteBufferBackedInputStream(ByteBuffer buf) {
  this.buf = buf;
 }
 public synchronized int read() throws IOException {
  if (!buf.hasRemaining()) {
   return -1;
  }
  return buf.get() & 0xFF;
 }
 @Override
 public int available() throws IOException {
  return buf.remaining();
 }
 public synchronized int read(byte[] bytes, int off, int len) throws IOException {
  if (!buf.hasRemaining()) {
   return -1;
  }
  len = Math.min(len, buf.remaining());
  buf.get(bytes, off, len);
  return len;
 }
}
而你是這樣的:
 String text = "this is text"; // It can be Unicode text
 ByteBuffer buffer = ByteBuffer.wrap(text.getBytes("UTF-8"));
 InputStream is = new ByteBufferBackedInputStream(buffer);
 InputStreamReader r = new InputStreamReader(is, "UTF-8");
 BufferedReader br = new BufferedReader(r);
 BufferedReader br = new BufferedReader(r);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM