Java InputStream problème de lecture
J'ai une classe Java, où je suis en train de lire des données dans un InputStream
byte[] b = null;
try {
b = new byte[in.available()];
in.read(b);
} catch (IOException e) {
e.printStackTrace();
}
Il fonctionne parfaitement quand je lance mon application à partir de l'IDE (Eclipse).
Mais lorsque j'exporte mon projet et il est emballé dans un BOCAL, la commande de lecture ne lit pas toutes les données. Comment pourrais-je résoudre ce problème?
Ce problème se produit principalement lorsque le InputStream est un Fichier (~10 ko).
Merci!
Il semblait donc que le système d'exploitation que vous exécutez eclipse retourné la taille totale d'un fichier lors de l'() a été appelé, mais ce n'est pas arrivé sur votre machine de test. Donc, ne comptez pas sur le nombre retourné par() comme le dit la java doc.
Classique de détournement de
Classique de détournement de
available()
. Il y a un avertissement dans la Javadoc particulier de l'utiliser de cette façon.
OriginalL'auteur Michael | 2011-05-28
Vous devez vous connecter pour publier un commentaire.
Habituellement, je préfère utiliser une taille fixe de la mémoire tampon lors de la lecture de flux d'entrée. Comme evilone a souligné, à l'aide de() en tant que taille de la mémoire tampon peut-être pas une bonne idée parce que, disons, si vous êtes à la lecture d'une ressource distante, alors vous pourriez ne pas savoir les octets disponibles à l'avance. Vous pouvez lire la javadoc de InputStream pour obtenir plus de perspicacité.
Voici l'extrait de code que j'utilise habituellement pour la lecture des flux d'entrée:
La version de read() que j'utilise ici va remplir le tampon, autant que possible, et
retourne le nombre d'octets réellement lus. De ce fait, il est possible que votre tampon peut contenir des données incorrectes à la fin des données, il est donc très important d'utiliser des octets seulement jusqu'à
bytesRead
.Remarque la ligne
(bytesRead = in.read(buffer)) >= 0
,il n'y a rien dans l'InputStream spec dire que read() ne peut pas lire 0 octets.Vous pourriez avoir besoin pour gérer le cas lorsque read() lit 0 octets en tant que cas particulier en fonction de votre cas. Pour fichier local je n'ai jamais connu de tels cas; toutefois, lorsque la lecture à distance de ressources, j'ai effectivement vu read() lit 0 octets constamment résultant le code ci-dessus dans une boucle infinie. J'ai résolu la boucle infinie problème en comptant le nombre de fois où j'lire 0 octets, lorsque le compteur dépasse un seuil, je vais jeter l'exception. Vous ne pouvez pas rencontrer ce problème, mais il suffit de garder cela à l'esprit 🙂Je vais probablement rester à l'écart de la création de nouveaux tableau d'octets pour chaque lecture pour des raisons de performances.
Le Javdoc pour
InputStream.read()
indique clairement qu'il bloque jusqu'à ce qu'au moins un octet est transféré ou à la fin de ruisseau ou une exception se produit. La seule façon pour elle de retourner zéro est si vous fournissez un zéro de la longueur de la mémoire tampon ou de comptage.Merci pour cette remarque, j'ai totalement raté que lorsque j'ai posté cette réponse. Cependant, il est toujours important de vérifier pour la lecture(...) renvoie 0 car selon les cas, certains cadres de revenir mise en œuvre de InputStream qui ont lu(...) return 0 même quand un tampon de longueur plus grande que 0.
Mais j'ai fait face à la lecture de 0 octets (pendant la lecture d'un contenu du fichier zip) dans la pratique, le scénario... j'ai Donc, il est toujours préférable de vérifier pour
bytesRead > 0
, je suppose...OriginalL'auteur Alvin
read()
sera de retour-1
lorsque l'InputStream est appauvri. Il existe également une version de lire qui prend un tableau, cela permet de faire un lit. Elle renvoie le nombre d'octets effectivement lus ou-1
quand à la fin de l'InputStream. Combinez cela avec une dynamique de la mémoire tampon comme ByteArrayOutputStream pour obtenir le suivant:Cela réduit beaucoup le nombre de méthodes que vous avez à invoquer et permet à l'ByteArrayOutputStream à cultiver la mémoire tampon interne plus rapide.
OriginalL'auteur jackrabbit
édité ma réponse
Vous pouvez obtenir une longueur du fichier directement, et vous devriez toujours
read()
dans une boucle (probablement pas, octet par octet, que cette réponse a) et de vérifier combien d'octets ont été retournés.read(byte[])
n'est pas garanti pour lire comme autant d'octets que vous le souhaitez.Autant que je sache toByteArray() lit à partir du flux d'entrée pour vous. Il n'y a pas besoin pour le code après la première ligne.
OriginalL'auteur evilone
Ci-dessous est un extrait de code qui télécharge un fichier (*. Png, *. Jpeg, *. Gif, ...) et de l'écrire dans BufferedOutputStream que représente le HttpServletResponse.
Espère que cette aide.
Le
ByteArrayOutputStream
est un gaspillage de temps et d'espace. L'entrée devrait être écrit directement à la sortie. Vous ne devriez pas avoir à régler la conttent de longueur.OriginalL'auteur Raimundo Espirito Santo