feat(download): 支持分区存储Uri下载模式
This commit is contained in:
@@ -19,7 +19,7 @@ import android.net.TrafficStats;
|
||||
import android.net.Uri;
|
||||
import android.os.Process;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.CompleteInfo;
|
||||
import com.arialyy.aria.core.common.RequestEnum;
|
||||
@@ -36,6 +36,7 @@ import com.arialyy.aria.util.CheckUtil;
|
||||
import com.arialyy.aria.util.CommonUtil;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
import com.arialyy.aria.util.RecordUtil;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -146,7 +147,9 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
|
||||
}
|
||||
long len = lenAdapter.handleFileLen(conn.getHeaderFields());
|
||||
|
||||
if (!FileUtil.checkMemorySpace(mEntity.getFilePath(), len)) {
|
||||
// 分区存储 Uri 任务写入的是 Uri(SAF / MediaStore),不校验本地存储空间
|
||||
if (TextUtils.isEmpty(mEntity.getFileUri())
|
||||
&& !FileUtil.checkMemorySpace(mEntity.getFilePath(), len)) {
|
||||
failDownload(new AriaHTTPException(
|
||||
String.format("下载失败,内存空间不足;filePath: %s, url: %s", mEntity.getFilePath(),
|
||||
mEntity.getUrl())), false);
|
||||
@@ -307,6 +310,12 @@ final class HttpDFileInfoTask implements IInfoTask, Runnable {
|
||||
ALog.w(TAG, "重命名失败【服务器返回的文件名为空】");
|
||||
return;
|
||||
}
|
||||
// 分区存储 Uri 任务写入的是 Uri,不支持重命名本地文件,仅使用服务器文件名作为展示名
|
||||
if (!TextUtils.isEmpty(mEntity.getFileUri())) {
|
||||
ALog.d(TAG, String.format("Uri 任务直接使用服务器文件名:%s", newName));
|
||||
mEntity.setFileName(newName);
|
||||
return;
|
||||
}
|
||||
ALog.d(TAG, String.format("文件重命名为:%s", newName));
|
||||
File oldFile = new File(mEntity.getFilePath());
|
||||
String newPath = oldFile.getParent() + "/" + newName;
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.arialyy.aria.core.task.IThreadTaskAdapter;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||
import com.arialyy.aria.util.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -18,6 +19,10 @@ final class HttpDTTBuilderAdapter extends AbsNormalTTBuilderAdapter {
|
||||
}
|
||||
|
||||
@Override public boolean handleNewTask(TaskRecord record, int totalThreadNum) {
|
||||
if (isUriMode()) {
|
||||
// 分区存储(Uri)模式没有本地临时文件,目标内容由ContentProvider管理,无需清理
|
||||
return true;
|
||||
}
|
||||
if (!record.isBlock) {
|
||||
if (getTempFile().exists()) {
|
||||
FileUtil.deleteFile(getTempFile());
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.arialyy.aria.http.download;
|
||||
|
||||
import com.arialyy.aria.core.AriaConfig;
|
||||
import com.arialyy.aria.core.common.RequestEnum;
|
||||
import com.arialyy.aria.core.common.SubThreadConfig;
|
||||
import com.arialyy.aria.core.download.DTaskWrapper;
|
||||
@@ -23,6 +24,8 @@ import com.arialyy.aria.http.BaseHttpThreadTaskAdapter;
|
||||
import com.arialyy.aria.http.ConnectionHelp;
|
||||
import com.arialyy.aria.util.ALog;
|
||||
import com.arialyy.aria.util.BufferedRandomAccessFile;
|
||||
import com.arialyy.aria.util.UriRandomAccessFile;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -100,6 +103,29 @@ final class HttpDThreadTaskAdapter extends BaseHttpThreadTaskAdapter {
|
||||
}
|
||||
|
||||
is = new BufferedInputStream(ConnectionHelp.convertInputStream(conn));
|
||||
if (getThreadConfig().tempUri != null) {
|
||||
// 分区存储:通过 Uri 写入,支持断点续传
|
||||
UriRandomAccessFile uriFile = null;
|
||||
try {
|
||||
uriFile = new UriRandomAccessFile(AriaConfig.getInstance().getAPP(),
|
||||
getThreadConfig().tempUri, getThreadRecord().startLocation);
|
||||
readNormal(is, uriFile);
|
||||
handleComplete();
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
fail(new AriaHTTPException(String.format("任务【%s】通过 Uri 下载失败,uri: %s, url: %s",
|
||||
getFileName(), getThreadConfig().tempUri, getThreadConfig().url), e), true);
|
||||
return;
|
||||
} finally {
|
||||
if (uriFile != null) {
|
||||
try {
|
||||
uriFile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mTaskOption.isChunked()) {
|
||||
readChunked(is);
|
||||
} else if (getThreadConfig().isBlock) {
|
||||
@@ -259,6 +285,31 @@ final class HttpDThreadTaskAdapter extends BaseHttpThreadTaskAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 分区存储:通过 Uri(FileChannel)写入数据,支持断点续传
|
||||
*/
|
||||
private void readNormal(InputStream is, UriRandomAccessFile file) throws IOException {
|
||||
byte[] buffer = new byte[getTaskConfig().getBuffSize()];
|
||||
int len;
|
||||
while (getThreadTask().isLive() && (len = is.read(buffer)) != -1) {
|
||||
if (getThreadTask().isBreak()) {
|
||||
break;
|
||||
}
|
||||
if (mSpeedBandUtil != null) {
|
||||
mSpeedBandUtil.limitNextBytes(len);
|
||||
}
|
||||
if (getThreadRecord().endLocation > 0
|
||||
&& getRangeProgress() + len >= getThreadRecord().endLocation) {
|
||||
len = (int) (getThreadRecord().endLocation - getRangeProgress());
|
||||
file.write(buffer, 0, len);
|
||||
progress(len);
|
||||
break;
|
||||
}
|
||||
file.write(buffer, 0, len);
|
||||
progress(len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理完成配置文件的更新或事件回调
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user