BufferedReader pour les grandes ByteBuffer?
Est-il un moyen de lire un ByteBuffer avec un BufferedReader sans avoir à le transformer en une Chaîne de caractères en premier? Je veux lire à travers une assez grande ByteBuffer que les lignes de texte et pour des raisons de performances, je veux éviter de les écrire sur le disque. Appeler toString sur le ByteBuffer ne fonctionne pas parce que la Chaîne résultante est trop grand (il jette java.lang.OutOfMemoryError: Java heap space). J'aurais pensé qu'il y aurait quelque chose dans l'API pour envelopper un ByteBuffer dans un lecteur, mais je n'arrive pas à trouver quelque chose de convenable.
Voici une présentation abrégée de code de l'échantillon de l'illustre ce que je fais):
//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
}
}
OriginalL'auteur Rob | 2009-06-25
Vous devez vous connecter pour publier un commentaire.
Il n'est pas clair pourquoi vous êtes à l'aide d'un tampon d'octets pour commencer. Si vous avez une
InputStream
et que vous voulez lire des lignes, pourquoi ne pas simplement utiliser unInputStreamReader
enveloppé dans unBufferedReader
? Quel est l'avantage de l'obtention de NIO impliqués?Appel
toString()
sur unByteArrayOutputStream
sonne comme une mauvaise idée pour moi, même si vous avez eu l'espace pour qu'il: mieux vaut l'avoir comme un tableau d'octets et de l'envelopper dans unByteArrayInputStream
et puis unInputStreamReader
, si vous devez vraiment avoir unByteArrayOutputStream
. Si vous vraiment voulez l'appelertoString()
, à moins d'utiliser la surcharge qui prend le nom de l'encodage des caractères à utiliser, sinon il va utiliser la valeur par défaut du système, qui n'est probablement pas ce que vous voulez.EDIT: Bon, si vous voulez vraiment utiliser NIO. Vous êtes encore à l'écriture d'un
ByteArrayOutputStream
finalement, de sorte que vous finirez avec un BAOS avec les données qu'il contient. Si vous voulez éviter de faire une copie de ces données, vous aurez besoin de tirer deByteArrayOutputStream
, par exemple comme ceci:Alors vous pouvez créer le flux d'entrée, de l'envelopper dans un
InputStreamReader
, étirable dans unBufferedReader
, et vous êtes loin.Afin de le mettre dans un tableau d'octets avec ByteArrayOutputStream. Une fois que vous avez comme un tableau d'octets, vous êtes fine. C'est effectivement ce que NIO va faire de toute façon, c'est juste plus simple avec BAOS. Si ça va être énorme, vous vous voulez tirer votre propre ByteArrayOutputStream qui vous donne un accès direct au tableau d'octets, de sorte que vous n'avez pas besoin de s'inquiéter à propos de la création d'une copie avec toByteArray(). C'est une honte ByteArrayOutputStream n'ont pas de "toByteArrayInputStream" pour vous permettre de lire directement à partir de la...
Quant à savoir pourquoi je suis en utilisant NIO: en partie parce que je suis masochiste et je suis déterminé à obtenir NIO compris une fois pour toutes (si c'est, en fait, il est humainement possible), et en partie parce que je veux lire l'InputStream aussi vite que possible et NIO semble plus rapide pour ce genre de chose.
Bon, si vous avez vraiment, vraiment envie d'utiliser NIO - édition de réponse.
OriginalL'auteur Jon Skeet
Vous pouvez utiliser NIO, mais il n'y a pas de réel besoin ici. Comme Jon Skeet suggéré:
OriginalL'auteur Matthew Flaschen
Ceci est un exemple:
Et vous pouvez l'utiliser comme ceci:
OriginalL'auteur user1079877