okHttp下载文件到本地存储

这里我们主要是用到response.body().byteStream()

response.body().byteStream() 是网络请求库(如 OkHttp )的常用方法,它在从服务器获取响应时将响应体作为一个 字节流InputStream)返回。这个方法通常用于处理大文件或数据流的下载,例如图片、视频、音频文件或其他二进制数据。

byteStream()byteStream() 方法返回一个 InputStream 对象,它代表响应体中的字节流。通过 InputStream,你可以逐字节地读取数据,非常适合处理大量的二进制数据(例如图片、视频文件、PDF 等)。

使用场景

  1. 下载大文件 :对于较大的文件或数据流,使用 byteStream() 方法可以有效避免将整个文件加载到内存中。它允许你逐块读取数据,减少内存消耗。

  2. 流式处理数据 :适用于需要对响应数据进行流式处理的场景。例如,当你处理的是音频或视频流时,可以使用 byteStream() 方法获取一个流,实时地解析或显示数据。

  3. 自定义数据处理 :在某些情况下,开发者可能希望按需自定义读取方式(如逐字节读取、分块处理等),byteStream() 提供了这种灵活性。

先定义个响应接口

java 复制代码
public interface DownloadCallback {
    void onProgress(int progress);

    void onSuccess(File file);

    void onFailure(String errorMessage);
}
java 复制代码
public class DownloadFile {

    private static OkHttpClient client = new OkHttpClient();

    public static void downloadFile(Activity activity, Context context, String fileUrl, String fileName, DownloadCallback callback) {

        String externalStorageDir = StringUtils.filePathDir();
        if (externalStorageDir == null) {
            callback.onFailure("External_storage_not_available");
            return;
        }
        String fileDir = externalStorageDir + "/Download/file";
        File fileDirFile = new File(fileDir);
        if (!fileDirFile.exists()) {
            boolean created = fileDirFile.mkdirs();
            if (!created) {
                callback.onFailure("Failed to create file");
                return;
            }
        }

        String filePath = fileDir + "/"+fileName;
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            try {
                boolean created = targetFile.createNewFile();
                if (!created) {
                    callback.onFailure("Failed to create file");
                    return;
                }
            } catch (IOException e) {
                callback.onFailure("Failed to create file: " + e.getMessage());
                return;
            }
        }
        Request request = new Request.Builder().url(fileUrl).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if (response.isSuccessful() && response.body() != null) {
                    long fileSize = Objects.requireNonNull(response.body()).contentLength();
                    long fileSizeDownloaded = 0;

                    //读入写出
                    try (InputStream inputStream = response.body().byteStream();
                         OutputStream outputStream = new FileOutputStream(targetFile)) {
                        byte[] buffer = new byte[4096];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                            fileSizeDownloaded += bytesRead;
                            int progress = (int) ((fileSizeDownloaded * 100) / fileSize);
                            //更新进度    
                            callback.onProgress(progress);
                        }
                        callback.onSuccess(targetFile);
                    } catch (IOException e) {
                        callback.onFailure(e.getMessage());
                    }
                } else {
                    callback.onFailure("Failed to download file");
                }
            }

            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                callback.onFailure("Failed to download file: " + e.getMessage());
            }
        });
    }
}
相关推荐
凌冰_4 天前
Vue 使用Ajax异步或同步
前端·ajax·okhttp
nee~4 天前
Charles抓包
okhttp
赵得C15 天前
AJAX拦截器失效排查指南:当你的beforeSend有效但error/complete沉默时
前端·ajax·okhttp
粤M温同学19 天前
Android OkHttp 框架超时设置详解
android·okhttp
粤M温同学19 天前
Android 使用OkHttp 下载文件失败问题定位和修复
okhttp
CUIYD_198920 天前
Ajax 核心知识点全面总结
前端·ajax·okhttp
weixin_4383354020 天前
Spring RestTemplate + MultiValueMap vs OkHttp 多值参数的处理
java·spring·okhttp
网络点点滴23 天前
上传一个菜谱-最后部分(项目完结)
android·okhttp
农业工作者23 天前
Android:使用OkHttp
android·okhttp
androidwork23 天前
Android 中 OkHttp 的自定义 Interceptor 实现统一请求头添加
android·java·okhttp·kotlin