ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
ArrayList<Byte> arrayList = new ArrayList<Byte>();
try {
while (responseStream.available() > 0) {
arrayList.add(responseStream.readByte());
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
Iterator<Byte> iterator = arrayList.iterator();
byte[] bytes = new byte[arrayList.size()];
int i = 0;
while (iterator.hasNext()) {
bytes[i++] = iterator.next();
}
Ce code est appelé à chaque chargement de page de mon application Web. Il semble fonctionner assez vite, mais y a-t-il quelque chose qui pourrait rendre cette course plus rapide?
Edit - Mise à jour à l'aide du flux de sortie de tableau d'octets
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
int read = responseStream.read();
while (read != -1) {
byteArrayOutputStream.write(read);
read = responseStream.read();
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
byte[] bytes = byteArrayOutputStream.toByteArray();
return ok(bytes).as(response.getHeader("Content-type"));
Edit - Code de test de référence
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
long t1 = System.nanoTime();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
int read = responseStream.read();
while (read != -1) {
byteArrayOutputStream.write(read);
read = responseStream.read();
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
byte[] bytes = byteArrayOutputStream.toByteArray();
long t2 = System.nanoTime();
System.out.println(t2-t1);
return ok(bytes).as(response.getHeader("Content-type"));
Durée moyenne après 100+ requête - 46873
ChannelBufferInputStream responseStream = (ChannelBufferInputStream) response.getBodyAsStream();
long t1 = System.nanoTime();
ArrayList<Byte> arrayList = new ArrayList<Byte>();
try {
while (responseStream.available() > 0) {
arrayList.add(responseStream.readByte());
}
} catch (IOException e) {
e.printStackTrace();
return internalServerError();
}
Iterator<Byte> iterator = arrayList.iterator();
byte[] bytes = new byte[arrayList.size()];
int i = 0;
while (iterator.hasNext()) {
bytes[i++] = iterator.next();
}
long t2 = System.nanoTime();
System.out.println(t2-t1);
return ok(bytes).as(response.getHeader("Content-type"));
Durée moyenne après 100+ requête - 522848
long t1 = System.nanoTime();
byte[] bytes;
try {
bytes = org.Apache.commons.io.IOUtils.toByteArray(responseStream);
} catch (Exception e) {
return internalServerError();
}
long t2 = System.nanoTime();
System.out.println(t2-t1);
Durée moyenne après 100+ requête - 45088
long t1 = System.nanoTime();
byte[] bytes;
try {
bytes = Sun.misc.IOUtils.readFully(responseStream, -1, true);
} catch (Exception e) {
return internalServerError();
}
long t2 = System.nanoTime();
System.out.println(t2 - t1);
Délai moyen après 100 requêtes + - 20180
Oui. Utilisez une ByteArrayOutputStream
plutôt qu'une ArrayList. Ensuite, lisez des fragments d'octets dans InputStream (sans utiliser available()
, qui ne devrait presque jamais être utilisé) et écrivez ces fragments dans ByteArrayOutputStream, jusqu'à ce que la méthode read()
renvoie -1. Ensuite, appelez toByteArray () sur votre ByteArrayOutputStream
.
Vous pouvez utiliser la méthode ByteStreams.toByteArray()
de Guava, qui fait tout cela pour vous, ou lire son code source pour avoir une meilleure idée de la façon dont il le fait. Lire le didacticiel IO pourrait également aider.
Quel est le problème avec Apache Commons IO IOUtils.toByteArray method? Cela a été optimisé pendant de nombreuses années à cette fin.
Pourquoi? Ce code est entièrement équivalent à read(byte[])
, sauf qu'il effectue deux étapes de copie supplémentaires sur l'ensemble des données. Tu n'as pas besoin de ça. Un simple read(byte[])
serait plusieurs fois plus rapide.
L'utilisation de available()
est également invalide. Vous avez besoin de la totalité de la réponse, pas seulement de la partie pouvant être lue sans blocage. Vous devez faire une boucle.