Java - Réinitialisation De InputStream
Je suis à traiter avec un code Java dans lequel il y a un InputStream que je l'ai lu en une fois, et puis j'ai besoin de le lire encore une fois de la même méthode.
Le problème est que j'ai besoin de réinitialiser la position de départ pour le lire deux fois.
J'ai trouvé un hack-ish solution au problème:
is.mark(Integer.MAX_VALUE);
//Read the InputStream is fully
//{ ... }
try
{
is.reset();
}
catch (IOException e)
{
e.printStackTrace();
}
Cette solution conduit à certaines unespected comportements? Ou il va travailler dans son mutisme?
Il peut échouer dans les situations que la lecture de code
Vous pouvez être en mesure d'étendre InputStream, remplacer la marque de la méthode, de sorte qu'il ne peut être appelé qu'une seule fois dans une instance.
mark()
.Vous pouvez être en mesure d'étendre InputStream, remplacer la marque de la méthode, de sorte qu'il ne peut être appelé qu'une seule fois dans une instance.
OriginalL'auteur iMineLink | 2013-09-13
Vous devez vous connecter pour publier un commentaire.
Comme l'écrit, vous n'avez aucune garantie, parce que
mark()
n'est pas nécessaire de déclarer si elle a réussi. Pour obtenir une garantie, vous devez d'abord appeler markSupported(), et il doit retournertrue
.Aussi comme l'écrit, la lecture de la limite est très dangereux. Si vous arrive d'être en utilisant un flux de tampons en mémoire, il est possible d'allouer de 2 go de mémoire tampon. D'autre part, si vous arrive d'être en utilisant un
FileInputStream
, vous êtes fine.Une meilleure approche est d'utiliser un
BufferedInputStream
explicite de la mémoire tampon.Oui, à condition que vous lui donnez un tampon assez grand. Il n'y a rien qui va comme par magie stocker des octets sans consommer de la mémoire. Si c'est un problème, vous aurez besoin de stocker les données dans un fichier local (je suis en supposant que, sur la base d'autres commentaires, que vous êtes en train de lire à partir d'une prise).
Ma faute de ne pas avoir bien précisé: je suis en train de lire à partir d'un InputStream retourné par un getResourceAsStream(xyz) qui, je pense, agit comme un FileInputStream. Je vais donc essayer en l'enveloppant dans un BufferedInputStream explicite taille de la mémoire tampon.
OriginalL'auteur kdgregory
Vous ne pouvez pas le faire de façon fiable; certains
InputStream
s (tels que ceux liés à des bornes ou des sockets) ne prennent pas en chargemark
etreset
(voirmarkSupported
). Si vous avez vraiment pour parcourir les données deux fois, vous avez besoin de lire dans votre propre tampon.OriginalL'auteur chrylis
Il dépend de l'InputStream mise en œuvre. Vous pouvez également penser que ce sera mieux si vous utilisez byte[]. Le plus simple est d'utiliser Apache commons-io:
Si vous utilisez SocketInputStream, vous ne pouvez pas utiliser la marque() pour lire plus d'une fois. Si vous n'avez pas assez de mémoire pour enregistrer le flux de données dans un tableau d'octets, vous pouvez essayer de rediriger l'InputStream données dans un fichier temporaire, et puis vous pouvez lire les données à partir de ce fichier, à l'aide de BufferedInputStream ( qui prend en charge mark() ) ou RandomAccessFile.
OriginalL'auteur stan
Au lieu d'essayer de réinitialiser le
InputStream
de le charger dans un tampon comme unStringBuilder
ou si c'est un flux de données binaires d'unByteArrayOutputStream
. Vous pouvez ensuite les processus de la mémoire tampon à l'intérieur de la méthode autant de fois que vous le souhaitez.OriginalL'auteur Ravi Thapliyal
Pour moi, la solution la plus simple est de passer de l'objet à partir de laquelle l'InputStream pourrait être obtenu, et juste l'obtenir de nouveau. Dans mon cas, c'était une
ContentResolver
.OriginalL'auteur androidguy