Qu'est-ce que InputStream.Disponible() faire en Java?
Que fait InputStream.available()
dans Java ? J'ai lu la documentation, mais je ne peux toujours pas le faire.
Le doc dit:
Renvoie le nombre d'octets qui peuvent être lus (ou ignorés) à partir de ce flux d'entrée sans blocage par l'appelant suivant d'une méthode pour ce flux d'entrée. L'appelant suivant peut être le même thread ou un autre thread.
La méthode disponible pour la classe InputStream renvoie toujours 0.
Que signifient-ils par blocage? Cela signifie-t-il simplement un appel synchronisé?
Et surtout, quel est le but de la méthode available()
?
4 réponses
Le blocage ne concerne pas le threading ou la synchronisation ici. Au lieu de cela, il concerne le blocage des E / S (Voir this pour plus d'informations). Si vous émettez une demande de lecture et que le canal n'est pas disponible, un appel de blocage attendra (ou bloquera) jusqu'à ce que les données soient disponibles (ou que le canal soit fermé, lève une exception, etc.)
Alors pourquoi utiliser available()
? Ainsi, vous pouvez déterminer le nombre d'octets à lire, ou déterminer si vous allez bloquer.
Notez que Java a des capacités d'E / S non bloquantes Aussi. Voir ici pour plus de détails,
Dans InputStreams, on dit que les appels read()
sont des appels de méthode" bloquants". Cela signifie que si aucune donnée n'est disponible au moment de l'appel de méthode, la méthode va attendre que les données soient disponibles.
La méthode available()
vous indique combien d'octets peuvent être lus jusqu'à ce que l'appel read()
bloque le flux d'exécution de votre programme. Sur la plupart des flux d'entrée, tous les appels à read()
bloquent, c'est pourquoi available renvoie 0 par défaut.
Cependant, sur certains flux (tels que BufferedInputStream
, cela avoir un tampon interne), certains octets sont lus et conservés en mémoire, de sorte que vous pouvez les lire sans bloquer le flux du programme. Dans ce cas, la méthode available()
vous indique combien d'octets sont conservés dans le tampon.
Considérez si vous écrivez un logiciel très mal.. et vous écrivez un système d'exploitation.
Ce système d'exploitation prend l'entrée du clavier entre autres choses.
Donc, vous demandez à votre système d'exploitation d'aller chercher une entrée au clavier, mais il n'y a pas de touches enfoncées et aucune dans le tampon. votre système D'exploitation entier restera alors mort jusqu'à ce qu'il obtienne une entrée au clavier.
Contrastez ceci avec 'look ahead', vous demandez si la base de connaissances a des caractères avant de faire l'appel. Vous obtenez la réponse non, donc votre système d'exploitation va alors et fait quelque chose d'autre.
C'est pourquoi vous devriez vous en soucier, maintenant si vous multipliez cela par toutes les autres tâches potentiellement bloquantes, vous pouvez voir pourquoi "regarder vers l'avenir" est critique.
Parce que cela s'applique également à la sortie: une mémoire vers une interface de lecteur de disque peut également inonder les données vers le lecteur de disque plus rapidement qu'elle ne peut les traiter. si vous ne savez pas que le tampon du lecteur est inondé de données, la tâche sera bloquée jusqu'à ce que le tampon puisse accepter plus de données.
Cela met également en évidence le non-sens de 'Il y a très peu d'utilisations utiles.'
L'un des éventuellement-pratiques usages de available()
l'utilise pour choisir une longueur de tampon raisonnable.
static final int LEN = 4096;
long copy(InputStream in, OutputStream out) throws IOException {
int count = 0L;
int avl = in.available();
if (avl == 0) {
// 0 returned without IOException? possibly mean eof?
return 0L;
}
//byte[] buf = new byte[avl == 0 ? LEN : Math.min(avl, LEN)];
byte[] buf = new byte[Math.min(avl, LEN)];
for (int len; (len = in.read(buf)) != -1; count+= len) {
out.write(buf, 0, len);
}
return count;
}
Le document dit,
Retourne: une estimation du nombre d'octets qui peut être lu (ou ignorée) à partir de ce flux d'entrée sans blocage ou
0
quand il atteint la fin du flux d'entrée.
Et
Une sous-classe' implémentation de cette méthode peut choisir de lancer un
IOException
si ce flux d'entrée a été fermé en appelant la méthodeclose()
.
Mise à JOUR
Je sais déjà que l'idée n'est pas recommandée. Je connaissais ce risque avant même que le doc du JDK ne l'ait averti. (J'ai déjà essayé d'allouer un tampon à partir du available
de quelques Go de taille FileInputStream
.)
Il n'est jamais correct d'utiliser la valeur de retour de cette méthode pour allouer un tampon destiné à contenir toutes les données flux.
Mais, en programmation, il ne devrait pas y avoir de code never
ou always wrong
.
C'est ce que je suis croyant.