OKHTTP에서 바이너리 파일 다운로드
내 안드로이드 응용 프로그램에서 네트워킹을 위해 OKHTTP 클라이언트를 사용하고 있습니다.
이 예제는 바이너리 파일을 업로드하는 방법을 보여줍니다. OKHTTP 클라이언트로 다운로드하는 바이너리 파일의 inputstream을 얻는 방법을 알고 싶습니다.
다음은 예제 목록입니다.
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);
}
}
}
간단한 get 요청의 현재 코드는 다음과 같습니다.
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();
이제 응답을 InputStream
. 응답을 Apache HTTP Client
위해 OkHttp
다음 과 같은 응답과 유사한 것 :
InputStream is = response.getEntity().getContent();
편집하다
아래에서 답변을 수락했습니다. 내 수정 된 코드 :
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();
OKHTTP에서 ByteStream 가져 오기
나는 OkHttp 의 문서를 파고 들었습니다. 이 방법으로 가야합니다.
이 방법을 사용하십시오.
response.body (). byteStream ()은 InputStream을 반환합니다.
따라서 단순히 BufferedReader 또는 다른 대안을 사용할 수 있습니다.
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();
InputStream in = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String result, line = reader.readLine();
result = line;
while((line = reader.readLine()) != null) {
result += line;
}
System.out.println(result);
response.body().close();
무엇의 가치를 위해, 나는 추천 response.body().source()
에서 okio 파일을 다운로드 할 때 올 수있는 많은 양의 데이터를 조작 할 수있는 쉬운 방법을 즐길하기 위해 (OkHttp 이미 기본적으로 지원하기 때문에).
@Override
public void onResponse(Call call, Response response) throws IOException {
File downloadedFile = new File(context.getCacheDir(), filename);
BufferedSink sink = Okio.buffer(Okio.sink(downloadedFile));
sink.writeAll(response.body().source());
sink.close();
}
InputStream과 비교하여 문서에서 가져온 몇 가지 이점 :
이 인터페이스는 기능적으로 InputStream과 동일합니다. InputStream은 소비 된 데이터가이기 종일 때 여러 레이어를 필요로합니다 : 원시 값을위한 DataInputStream, 버퍼링을위한 BufferedInputStream, 문자열을위한 InputStreamReader. 이 클래스는 위의 모든 항목에 BufferedSource를 사용합니다. Source는 구현 불가능한 available () 메서드를 피합니다. 대신 호출자는 필요한 바이트 수를 지정합니다.
Source는 InputStream에 의해 추적되는 unsafe-to-compose 표시 및 재설정 상태를 생략합니다. 대신 호출자는 필요한 것을 버퍼링합니다.
소스를 구현할 때 효율적으로 구현하기 어색하고 257 개의 가능한 값 중 하나를 반환하는 단일 바이트 읽기 메서드에 대해 걱정할 필요가 없습니다.
소스에는 더 강력한 스킵 메소드가 있습니다. BufferedSource.skip (long)은 너무 일찍 반환되지 않습니다.
다운로드하기 가장 좋은 옵션 (소스 코드 "okio"기반)
private void download(@NonNull String url, @NonNull File destFile) throws IOException {
Request request = new Request.Builder().url(url).build();
Response response = okHttpClient.newCall(request).execute();
ResponseBody body = response.body();
long contentLength = body.contentLength();
BufferedSource source = body.source();
BufferedSink sink = Okio.buffer(Okio.sink(destFile));
Buffer sinkBuffer = sink.buffer();
long totalBytesRead = 0;
int bufferSize = 8 * 1024;
for (long bytesRead; (bytesRead = source.read(sinkBuffer, bufferSize)) != -1; ) {
sink.emit();
totalBytesRead += bytesRead;
int progress = (int) ((totalBytesRead * 100) / contentLength);
publishProgress(progress);
}
sink.flush();
sink.close();
source.close();
}
다음은 청크 다운로드 후 다운로드 진행률을 게시하는 동안 Okhttp + Okio 라이브러리를 사용하는 방법입니다 .
public static final int DOWNLOAD_CHUNK_SIZE = 2048; //Same as Okio Segment.SIZE
try {
Request request = new Request.Builder().url(uri.toString()).build();
Response response = client.newCall(request).execute();
ResponseBody body = response.body();
long contentLength = body.contentLength();
BufferedSource source = body.source();
File file = new File(getDownloadPathFrom(uri));
BufferedSink sink = Okio.buffer(Okio.sink(file));
long totalRead = 0;
long read = 0;
while (read = (source.read(sink.buffer(), DOWNLOAD_CHUNK_SIZE)) != -1) {
totalRead += read;
int progress = (int) ((totalRead * 100) / contentLength);
publishProgress(progress);
}
sink.writeAll(source);
sink.flush();
sink.close();
publishProgress(FileInfo.FULL);
} catch (IOException e) {
publishProgress(FileInfo.CODE_DOWNLOAD_ERROR);
Logger.reportException(e);
}
더 나은 솔루션은 OkHttpClient를 다음과 같이 사용하는 것입니다.
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
// Headers responseHeaders = response.headers();
// for (int i = 0; i < responseHeaders.size(); i++) {
// System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
// }
// System.out.println(response.body().string());
InputStream in = response.body().byteStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String result, line = reader.readLine();
result = line;
while((line = reader.readLine()) != null) {
result += line;
}
System.out.println(result);
}
});
참고 URL : https://stackoverflow.com/questions/25893030/download-binary-file-from-okhttp
'Programing' 카테고리의 다른 글
putty를 사용하여 sql.gz 파일을 데이터베이스로 가져오고 삽입하십시오. (0) | 2020.11.16 |
---|---|
필수 필드에 별표를 표시하도록 LabelFor를 수정하려면 어떻게해야합니까? (0) | 2020.11.16 |
Angular 4.3-HttpClient 설정 매개 변수 (0) | 2020.11.16 |
ActiveRecord 날짜 필드에서 연도, 일 또는 월로 찾기 (0) | 2020.11.16 |
Bootstrap 3으로 자리 표시 자 색상을 변경하지 못함 (0) | 2020.11.16 |