okHttp下载文件到本地存储
这里我们主要是用到response.body().byteStream()
response.body().byteStream()
是网络请求库(如 OkHttp)的常用方法,它在从服务器获取响应时将响应体作为一个 字节流(InputStream
)返回。这个方法通常用于处理大文件或数据流的下载,例如图片、视频、音频文件或其他二进制数据。
byteStream()
:byteStream()
方法返回一个 InputStream
对象,它代表响应体中的字节流。通过 InputStream
,你可以逐字节地读取数据,非常适合处理大量的二进制数据(例如图片、视频文件、PDF 等)。
使用场景
-
下载大文件:对于较大的文件或数据流,使用
byteStream()
方法可以有效避免将整个文件加载到内存中。它允许你逐块读取数据,减少内存消耗。 -
流式处理数据:适用于需要对响应数据进行流式处理的场景。例如,当你处理的是音频或视频流时,可以使用
byteStream()
方法获取一个流,实时地解析或显示数据。 -
自定义数据处理:在某些情况下,开发者可能希望按需自定义读取方式(如逐字节读取、分块处理等),
byteStream()
提供了这种灵活性。
先定义个响应接口
public interface DownloadCallback {void onProgress(int progress);void onSuccess(File file);void onFailure(String errorMessage);
}
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() {@Overridepublic 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");}}@Overridepublic void onFailure(@NonNull Call call, @NonNull IOException e) {callback.onFailure("Failed to download file: " + e.getMessage());}});}
}