7
votes

DatainputStream.Read Renvoie moins que Len

J'utilise DataGuTReam pour lire des octets à partir d'une prise. J'ai un nombre attendu d'octets à lire dans le flux (après avoir décodé un en-tête, je sais combien d'octets sont dans le message) Cela fonctionne 99% du temps, mais je ferai parfois le nombre d'octets que la lecture soit inférieure à Len em>.

int numRead = dis.read(buffer, 0, len);


0 commentaires

5 Réponses :


12
votes

Edit: Pour un flux général, vous continuez à lire jusqu'à ce que vous ayez lu tout ce que vous voulez, fondamentalement. Pour une implémentation de Datainput (tel que DataGuTretstream ), vous devez utiliser lue , comme suggéré par Peter Lawrey. Considérez le reste de cette réponse à être pertinent pour l'affaire Général où vous avez simplement un InputStreream .

C'est entièrement raisonnable pour un Inpurstream de tout type pour vous donner moins de données que vous avez demandé, même si plus est sur son chemin. Vous devez toujours coder pour cette possibilité - avec l'exception possible de byteArrayInputStream . (Cela peut toujours retourner moins de données que ce qui a été demandé, bien sûr, s'il y a moins de données gauche que vous avez demandé.)

Voici le genre de boucle dont je parle: xxx


4 commentaires

byteArrayInputStream va toujours lire moins que demandé si vous atteignez sa fin.


@Stephen: C'est vrai, mais si vous savez absolument qu'il y a plus de données là-bas, alors je serais très surpris de le voir renvoyer moins de données. Je vais éditer pour clarifier cependant.


Belle explication de ce qui se passait. Cependant, je pense que la suggestion de Peter Lawrey à utiliser avec une grande quantité est plus propre que d'utiliser une boucle de temps pour lire la totalité de données.


@Dunes: Dans le cas de Datainputtream, vous avez absolument raison :) J'avais manqué ça. Utile pour avoir la version en boucle pour non-Datainput. Va éditer.



0
votes

lire les retours à chaque fois avec les bits disponibles à cette époque et -1 lorsque vous avez terminé, vous êtes généralement censé faire

while (true) {
  int numRead = dis.read(buffer, 0, len);
  if (numRead == -1) break;
  total.append(buffer, numRead);
}


1 commentaires

Ouais, Len peut être constant ici par exemple. 1024



8
votes

Vous pouvez utiliser DataGuThetstream de cette façon. XXX

Ceci reviendra avec toutes les données Lecture ou lancez une IOException.


0 commentaires

0
votes

Je m'attendrais à ce que le comportement de lire bloquer jusqu'à ce que le flux soit fermé ou EOF est atteint.

Ensuite, vous devez vérifier les Javadocs. Le contrat de lecture () est qu'il lira au moins un octet, bloquant si nécessaire jusqu'à ce qu'il soit fait, ou jusqu'à ce que les EOS ou une exception se produisent. Il n'y a rien dans la spécification qui dit qu'il lit toute la longueur que vous avez demandée. C'est pourquoi il retourne une longueur.


0 commentaires

0
votes

Y a-t-il un moyen de lire des octets à partir d'une prise qui vous assurera toujours de lire des octets Len?

Vous pouvez utiliser Apache Commons IOUTILS, ils ont une méthode qui fait exactement ce dont vous avez besoin: xxx


0 commentaires