Télécharger le fichier binaire de OKHTTP
Je suis en utilisant OKHTTP client pour la mise en réseau dans mon application android.
Cette exemple montre comment télécharger des fichier binaire. Je voudrais savoir comment obtenir de l'inputstream de fichier binaire à télécharger avec OKHTTP client.
Voici la liste de l'exemple :
public class InputStreamRequestBody extends RequestBody {
private InputStream inputStream;
private MediaType mediaType;
public static RequestBody create(final MediaType mediaType,
final InputStream inputStream) {
return new InputStreamRequestBody(inputStream, mediaType);
}
private InputStreamRequestBody(InputStream inputStream, MediaType mediaType) {
this.inputStream = inputStream;
this.mediaType = mediaType;
}
@Override
public MediaType contentType() {
return mediaType;
}
@Override
public long contentLength() {
try {
return inputStream.available();
} catch (IOException e) {
return 0;
}
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
Source source = null;
try {
source = Okio.source(inputStream);
sink.writeAll(source);
} finally {
Util.closeQuietly(source);
}
}
}
Code actuel pour la simple requête get est:
OkHttpClient client = new OkHttpClient();
request = new Request.Builder().url("URL string here")
.addHeader("X-CSRFToken", csrftoken)
.addHeader("Content-Type", "application/json")
.build();
response = getClient().newCall(request).execute();
Maintenant, comment puis-je convertir la réponse à InputStream
. Quelque chose qui ressemble à la réponse de Apache HTTP Client
comme cela pour OkHttp
réponse:
InputStream is = response.getEntity().getContent();
MODIFIER
Accepté de répondre à partir de ci-dessous.
Mon code modifié:
request = new Request.Builder().url(urlString).build();
response = getClient().newCall(request).execute();
InputStream is = response.body().byteStream();
BufferedInputStream input = new BufferedInputStream(is);
OutputStream output = new FileOutputStream(file);
byte[] data = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
- vérifier mon édité réponse, je suis en attente de vos commentaires
- Merveilleux!
- heureux, il a travaillé pour vous l'homme 😀
- comme une note de côté, votre InputStreamRequestBody n'est pas d'aller travailler si il y a une ioexception de la demande et de la HttpEngine est fixé à réessayer. Voir github.com/square/okhttp/blob/master/okhttp/src/main/java/com/... la ligne 202, writeTo est appelée dans une boucle while. Il va provoquer une erreur. (Je suis tombé sur ce pendant le téléchargement à partir d'un
content://
inputstream)
Vous devez vous connecter pour publier un commentaire.
Arriver ByteStream de OKHTTP
J'ai fouiné partout dans la Documentation de OkHttp vous avez besoin pour aller de cette façon
utiliser cette méthode :
de sorte que vous pouvez simplement utiliser un BufferedReader ou de toute autre alternative
BufferedReader
avec les données binaires; il sera corrompu par l'inutile octet par caractère de décodage.Pour ce que ça vaut, je vous recommande
response.body().source()
de okio (depuis OkHttp est prise en charge en mode natif) afin de bénéficier d'un moyen plus facile de manipuler une grande quantité de données qui peuvent arriver lors du téléchargement d'un fichier.Quelques avantages prises à partir de la documentation en comparaison avec InputStream:
while ((source.read(fileSink, 2048)) != -1)
. Dans ce code j'ai un problème avec le casting: Tampon besoins, mais BufferedSink trouvé.while ((source.read(fileSink.buffer(), 2048)) != -1)
La meilleure option pour télécharger (basé sur le code source "okio")
flush()
etclose()
méthodes dans unfinally
bloc pour s'assurer que toutes les exceptions seront toujours rincer et de les fermer.C'est la façon dont j'utilise Okhttp + Okio bibliothèques lors de la publication de la progression du téléchargement après chaque morceau de téléchargement:
getDownloadPathFrom
faire ?while (read = (source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
devrait êtrewhile ((read = source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
sink.emit();
dans lewhile
cycle, vous allez utiliser une grande quantité de mémoire.sink.flush()
écrire toutes les données dans le fichier ici. Pourquoi devons-nous fairesink.writeAll
?Meilleure solution est d'utiliser OkHttpClient comme: