2010-12-03 15 views

Répondre

1

La méthode read(byte[]) sur les flux Java peut lire moins d'octets que demandé.

Par fichier sur Internet Je suppose que vous voulez dire le contenu d'une URL HTTP.

Certaines réponses HTTP ne donneront pas une longueur de contenu à l'avance, ce qui ne permet pas non plus de pré-allouer un tableau d'octets de la bonne taille comme vous semblez le faire.

Vous pouvez être intéressé de savoir que la bibliothèque cliente Apache http disponible sur Android fournit déjà une méthode d'assistance EntityUtils.toByteArray() qui récupère complètement le contenu d'une URL et la renvoie sous la forme d'un tableau d'octets correctement dimensionné.

est ici un morceau de code utilisant:

public byte[] fetchURL(String url) throws IOException, ClientProtocolException { 
     HttpClient httpclient = new DefaultHttpClient(); 
     HttpGet httpget = new HttpGet(url); 
     HttpResponse response = httpclient.execute(httpget); 
     HttpEntity entity = response.getEntity(); 
     return EntityUtils.toByteArray(entity); 
} 

Notez que la lecture de la réponse entière dans la mémoire n'est pas toujours la meilleure solution. Il peut être préférable de signaler la progression du téléchargement à l'utilisateur ou d'analyser un grand document de façon incrémentielle. En fait, une réponse peut même ne pas tenir dans la RAM (par exemple un grand flux vidéo).

1

La commande de lecture normale lit un nombre d'octets jusqu'à la longueur demandée. Il appartient au programmeur d'inclure une vérification de la valeur de retour (qui vous indique combien d'octets ont été lus). Il y a aussi la méthode readFully qui l'oblige à lire toute la longueur demandée, mais qui a le potentiel de bloquer pendant très longtemps, vous empêchant d'éclater au milieu de la lecture d'un grand flux.

1

Y at-il une raison pour laquelle mon tableau d'octets ne devrait être rempli que partiellement après l'appel?

Oui. Pour que votre application Android ne doit pas attendre le téléchargement complet du flux avant de revenir de l'appel read.

Dans votre cas d'utilisation particulier, ceci est (apparemment) une nuisance. Dans d'autres cas d'utilisation, il est une condition essentielle que read se comporte de cette façon:

  • L'application peut être nécessaire de commencer le traitement et la livraison des résultats à l'utilisateur tout serveur distant envoie toujours les données.

  • Le serveur distant peut réellement attendre une réponse de niveau application de la part du client avant d'envoyer plus de données. (Cela ne s'appliquera pas si vous utilisez HTTP ou FTP, mais le flux que vous lisez est probablement en train d'encapsuler un flux Socket de couche transport, et à ce niveau, il n'y a aucune connaissance sur les détails du protocole de couche de présentation.)

La solution consiste à:

  • utiliser une boucle et de garder la lecture jusqu'à ce que read renvoie zéro.
  • Si vous utilisez Apache HttpClient, il existe des moyens d'obtenir le contenu entier d'une réponse.
  • Apache Commons inclut une classe IOUtils qui a des méthodes d'aide pour lire un flux entier ou un lecteur. BTW, ce comportement est clairement spécifié dans les javadocs pour les méthodes read(byte[], ...)