android - दशमलव - OKHTTP से बाइनरी फ़ाइल डाउनलोड करें




हेक्साडेसीमल नंबर सिस्टम (4)

इस तरह मैं प्रत्येक चुंक डाउनलोड के बाद डाउनलोड प्रगति प्रकाशित करते समय 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);
}

मैं अपने एंड्रॉइड एप्लिकेशन में नेटवर्किंग के लिए OKHTTP क्लाइंट का उपयोग कर रहा हूं।

This उदाहरण दिखाता है कि बाइनरी फ़ाइल कैसे अपलोड करें। मैं जानना चाहता हूं कि OKHTTP क्लाइंट के साथ बाइनरी फ़ाइल डाउनलोड करने के इनपुटस्ट्रीम को कैसे प्राप्त किया जाए।

उदाहरण की सूची यहां दी गई है:

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);
        }
    }
}

सरल अनुरोध के लिए वर्तमान कोड है:

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 को प्रतिक्रिया कैसे परिवर्तित करूं? OkHttp प्रतिक्रिया के लिए इस तरह Apache HTTP Client से प्रतिक्रिया के समान कुछ:

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();

इसके लायक होने के लिए, मैं एक फ़ाइल डाउनलोड करते समय आने वाली बड़ी मात्रा में डेटा में हेरफेर करने के लिए एक आसान तरीका का आनंद लेने के लिए okio से response.body().source() (ओकेएचटीपी पहले से ही इसका समर्थन कर रहा है response.body().source() की सिफारिश करता हूं।

@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();
}

इनपुटस्ट्रीम की तुलना में दस्तावेज़ीकरण से लिया गया कुछ फायदे:

यह इंटरफ़ेस कार्यात्मक रूप से इनपुटस्ट्रीम के बराबर है। डेटास्ट्रीम को कई परतों की आवश्यकता होती है जब उपभोग डेटा डेटा विषम होता है: मूलभूत मानों के लिए डेटा इनपुटस्ट्रीम, बफरिंग के लिए एक बुफर्डइनपुटस्ट्रीम, और स्ट्रिंग के लिए इनपुटस्ट्रीम रीडर। यह वर्ग उपर्युक्त सभी के लिए बुफर्डसोर्स का उपयोग करती है। स्रोत असंभव-से-लागू उपलब्ध () विधि से बचाता है। इसके बजाय कॉलर्स निर्दिष्ट करते हैं कि उन्हें कितने बाइट चाहिए।

स्रोत असुरक्षित-टू-कंपोज़ चिह्न को छोड़ देता है और इनपुट स्थिति को ट्रैक करता है जो इनपुटस्ट्रीम द्वारा ट्रैक किया जाता है; कॉलर्स इसके बजाय बस उन्हें जो चाहिए उसे बफर करें।

किसी स्रोत को लागू करते समय, आपको एकल-बाइट रीड विधि के बारे में चिंता करने की आवश्यकता नहीं होती है जो कुशलतापूर्वक कार्यान्वित करने के लिए अजीब है और यह 257 संभावित मानों में से एक देता है।

और स्रोत में एक मजबूत स्किप विधि है: BufferedSource.skip (लंबा) समय से पहले वापस नहीं आएगा।


बेहतर समाधान 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);


                }
            });

OKHTTP से बाइटस्ट्रीम प्राप्त करना

मैं ओकेएचटीपी के दस्तावेज़ीकरण में खुदाई कर रहा हूं, आपको इस तरह से जाने की जरूरत है

इस विधि का प्रयोग करें:

respond.body ()। बाइटस्ट्रीम () जो एक इनपुटस्ट्रीम लौटाएगा

तो आप बस एक 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();




okhttp