Gibt es eine Möglichkeit, einen ByteBuffer mit einem BufferedReader zu lesen, ohne ihn erst zu einem String machen zu müssen? Ich möchte einen ziemlich großen ByteBuffer als Textzeilen durchlesen und aus Performance-Gründen möchte ich vermeiden, es auf die Festplatte zu schreiben. Der Aufruf von toString auf dem ByteBuffer funktioniert nicht, da der resultierende String zu groß ist (er löst java.lang.OutOfMemoryError: Java-Heapspeicher aus). Ich hätte gedacht, dass es etwas in der API geben würde, um einen ByteBuffer in einem geeigneten Leser zu verpacken, aber ich finde nichts passendes.BufferedReader für großen ByteBuffer?
Hier ist eine verkürzte Codebeispiel das zeigt, was ich tue):
// 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
}
}
Gute Frage - ich würde zustimmen, und das ist, was ich tun würde, wenn ich die Option hätte. Der Grund, warum ich in diesem Fall nicht kann, ist, dass ich nichts mit der Ausgabe aus dem Prozess (d. H. Dem InputStream) tun kann, bis der Prozess beendet ist, also muss ich ihn in einen Puffer setzen, um ihn später zu lesen. – Rob
Also in ein Byte-Array mit ByteArrayOutputStream. Sobald Sie es als Byte-Array haben, geht es Ihnen gut. Das ist effektiv, was NIO sowieso machen wird, es ist einfacher mit BAOS. Wenn es gewaltig wird, möchten Sie möglicherweise Ihren eigenen ByteArrayOutputStream ableiten, der Ihnen direkten Zugriff auf das Byte-Array gibt, so dass Sie sich keine Gedanken über das Erstellen einer Kopie mit toByteArray() machen müssen. Es ist eine Schande, ByteArrayOutputStream hat keine "toByteArrayInputStream", damit Sie direkt von ihm lesen ... –
Warum ich NIO benutze: teilweise, weil ich ein Masochist bin und bin entschlossen, NIO einmal und für herauszufinden alle (wenn das tatsächlich menschenmöglich ist), und teilweise, weil ich den InputStream so schnell wie möglich lesen möchte und NIO für solche Dinge schneller scheint. – Rob