修复部分ftp服务器下载文件失败的问题

pull/330/head
e 7 years ago
parent f3cb7b601a
commit 88dfa7eedc
  1. 4
      Aria/build.gradle
  2. 2
      Aria/src/main/java/com/arialyy/aria/core/AriaManager.java
  3. 21
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpInfoThread.java
  4. 3
      Aria/src/main/java/com/arialyy/aria/core/common/AbsFtpThreadTask.java
  5. 19
      Aria/src/main/java/com/arialyy/aria/core/download/downloader/FtpThreadTask.java
  6. 23
      Aria/src/main/java/com/arialyy/aria/core/upload/uploader/FtpThreadTask.java
  7. 3
      Aria/src/main/java/com/arialyy/aria/util/CommonUtil.java
  8. 2
      DEV_LOG.md
  9. 16
      README.md
  10. 7
      app/src/main/java/com/arialyy/simple/download/FtpDownloadActivity.java
  11. 22
      app/src/main/java/com/arialyy/simple/download/SingleTaskActivity.java

@ -23,8 +23,8 @@ dependencies {
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1' compile 'com.android.support:appcompat-v7:23.1.1'
compile project(':AriaAnnotations') compile project(':AriaAnnotations')
compile 'com.arialyy.aria:aria-ftp-plug:1.0.3' // compile 'com.arialyy.aria:aria-ftp-plug:1.0.3'
// compile project(':AriaFtpPlug') compile project(':AriaFtpPlug')
} }
apply from: 'bintray-release.gradle' apply from: 'bintray-release.gradle'

@ -69,8 +69,6 @@ import org.xml.sax.SAXException;
public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/"; public static final String DOWNLOAD_TEMP_DIR = "/Aria/temp/download/";
public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/"; public static final String UPLOAD_TEMP_DIR = "/Aria/temp/upload/";
@SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null; @SuppressLint("StaticFieldLeak") private static volatile AriaManager INSTANCE = null;
private Map<String, AbsReceiver> mReceivers = new ConcurrentHashMap<>(); private Map<String, AbsReceiver> mReceivers = new ConcurrentHashMap<>();
public static Context APP; public static Context APP;

@ -23,6 +23,7 @@ import com.arialyy.aria.core.inf.AbsTaskEntity;
import com.arialyy.aria.core.upload.UploadEntity; import com.arialyy.aria.core.upload.UploadEntity;
import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.Regular; import com.arialyy.aria.util.Regular;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -77,11 +78,18 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
String remotePath = String remotePath =
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET); new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET);
FTPFile[] files = client.listFiles(remotePath); FTPFile[] files = client.listFiles(remotePath);
String s = client.getReplyString();
ALog.w(TAG, s);
boolean isExist = files.length != 0; boolean isExist = files.length != 0;
if (!isExist && !isUpload) { if (!isExist && !isUpload) {
failDownload("文件不存在,任务链接【" + mTaskEntity.urlEntity.url + "】", false); failDownload("文件不存在,任务链接【" + mTaskEntity.urlEntity.url + "】", false);
FTPFile[] files1 = client.listFiles(); int i = remotePath.lastIndexOf(File.separator);
FTPFile[] files1;
if (i == -1) {
files1 = client.listFiles();
} else {
files1 = client.listFiles(remotePath.substring(0, i + 1));
}
if (files1.length > 0) { if (files1.length > 0) {
ALog.i(TAG, "路径【" + setRemotePath() + "】下的文件列表 ==================================="); ALog.i(TAG, "路径【" + setRemotePath() + "】下的文件列表 ===================================");
for (FTPFile file : files1) { for (FTPFile file : files1) {
@ -105,7 +113,7 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
mTaskEntity.isNewTask = true; mTaskEntity.isNewTask = true;
} else { } else {
client.disconnect(); client.disconnect();
failDownload("获取文件信息错误,错误码为:" + reply, true); failDownload("获取文件信息错误,错误码为:" + reply + ",msg:" + client.getReplyString(), true);
return; return;
} }
} }
@ -196,13 +204,14 @@ public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY ext
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect(); client.disconnect();
failDownload("无法连接到ftp服务器,错误码为:" + reply, true); failDownload("无法连接到ftp服务器,错误码为:" + reply + ",msg:" + client.getReplyString(), true);
return null; return null;
} }
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码 // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
charSet = "UTF-8"; charSet = "UTF-8";
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion( reply = client.sendCommand("OPTS UTF8", "ON");
client.sendCommand("OPTS UTF8", "ON"))) { if (!TextUtils.isEmpty(mTaskEntity.charSet) || (!FTPReply.isPositiveCompletion(reply)
&& reply != FTPReply.COMMAND_OK)) {
ALog.i(TAG, "FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码"); ALog.i(TAG, "FTP 服务器不支持开启UTF8编码,尝试使用Aria手动设置的编码");
charSet = mTaskEntity.charSet; charSet = mTaskEntity.charSet;
} }

@ -87,7 +87,8 @@ public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTI
int reply = client.getReplyCode(); int reply = client.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) { if (!FTPReply.isPositiveCompletion(reply)) {
client.disconnect(); client.disconnect();
fail(STATE.CURRENT_LOCATION, "无法连接到ftp服务器,错误码为:" + reply, null); fail(STATE.CURRENT_LOCATION,
"无法连接到ftp服务器,错误码为:" + reply + ",msg:" + client.getReplyString(), null);
return null; return null;
} }
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码 // 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码

@ -59,17 +59,30 @@ class FtpThreadTask extends AbsFtpThreadTask<DownloadEntity, DownloadTaskEntity>
+ "】"); + "】");
client = createClient(); client = createClient();
if (client == null) return; if (client == null) return;
if (mConfig.START_LOCATION > 0) {
client.setRestartOffset(mConfig.START_LOCATION); client.setRestartOffset(mConfig.START_LOCATION);
}
//发送第二次指令时,还需要再做一次判断
int reply = client.getReplyCode();
if (reply == FTPReply.SYNTAX_ERROR_IN_ARGUMENTS) {
ALog.e(TAG, "FTP没有打开写权限,断点续传失败,将从0开始读文件");
} else if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.COMMAND_OK) {
client.disconnect();
fail(mChildCurrentLocation, "获取文件信息错误,错误码为:" + reply + ",msg:" + client.getReplyString(),
null);
return;
}
String remotePath = String remotePath =
new String(mTaskEntity.urlEntity.remotePath.getBytes(charSet), SERVER_CHARSET); new String(mTaskEntity.urlEntity.remotePath.getBytes(charSet), SERVER_CHARSET);
is = client.retrieveFileStream(remotePath); is = client.retrieveFileStream(remotePath);
//发送第二次指令时,还需要再做一次判断 reply = client.getReplyCode();
int reply = client.getReplyCode();
if (!FTPReply.isPositivePreliminary(reply)) { if (!FTPReply.isPositivePreliminary(reply)) {
client.disconnect(); client.disconnect();
fail(mChildCurrentLocation, "获取文件信息错误,错误码为:" + reply, null); fail(mChildCurrentLocation, "获取流失败,错误码为:" + reply + ",msg:" + client.getReplyString(),
null);
return; return;
} }
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize); file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
file.seek(mConfig.START_LOCATION); file.seek(mConfig.START_LOCATION);
byte[] buffer = new byte[mBufSize]; byte[] buffer = new byte[mBufSize];

@ -61,9 +61,28 @@ class FtpThreadTask extends AbsFtpThreadTask<UploadEntity, UploadTaskEntity> {
client = createClient(); client = createClient();
if (client == null) return; if (client == null) return;
initPath(); initPath();
client.makeDirectory(dir); if (client.makeDirectory(dir)) {
client.changeWorkingDirectory(dir); fail(mChildCurrentLocation, "创建文件夹失败", null);
return;
}
if (client.changeWorkingDirectory(dir)) {
fail(mChildCurrentLocation, "选择工作文件夹失败", null);
return;
}
client.setRestartOffset(mConfig.START_LOCATION); client.setRestartOffset(mConfig.START_LOCATION);
int reply = client.getReplyCode();
if (reply == FTPReply.SYNTAX_ERROR_IN_ARGUMENTS) {
client.disconnect();
fail(mChildCurrentLocation,
"上传失败,FTP没有打开写权限,错误码为:" + reply + ",msg:" + client.getReplyString(), null);
return;
} else if (!FTPReply.isPositivePreliminary(reply) && reply != FTPReply.COMMAND_OK) {
client.disconnect();
fail(mChildCurrentLocation,
"上传失败,FTP没有打开写权限,错误码为:" + reply + ",msg:" + client.getReplyString(), null);
return;
}
file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize); file = new BufferedRandomAccessFile(mConfig.TEMP_FILE, "rwd", mBufSize);
if (mConfig.START_LOCATION != 0) { if (mConfig.START_LOCATION != 0) {
//file.skipBytes((int) mConfig.START_LOCATION); //file.skipBytes((int) mConfig.START_LOCATION);

@ -103,7 +103,8 @@ public class CommonUtil {
entity.hostName = str; entity.hostName = str;
} }
entity.port = m.group(3); entity.port = m.group(3);
entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : "/" + m.group(4); //entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : "/" + m.group(4);
entity.remotePath = TextUtils.isEmpty(m.group(4)) ? "/" : m.group(4);
} }
return entity; return entity;
} }

@ -1,5 +1,5 @@
## 开发日志 ## 开发日志
+ v_3.3.12 + v_3.3.13
- 添加`@Download.onWait、@Upload.onWait、@DownloadGroup.onWait`三个新注解,队列已经满了,继续创建新任务,任务处于等待中,将会执行被这三个注解标志的方法 - 添加`@Download.onWait、@Upload.onWait、@DownloadGroup.onWait`三个新注解,队列已经满了,继续创建新任务,任务处于等待中,将会执行被这三个注解标志的方法
- app被kill,但是还存在等待中的任务A;第二次重新启动,先创建一个新的任务B,Aria会自动把B放进等待队列中,这时再次创建任务A,会导致重复下载,进度错乱的问题;本版本已修复这个问题 - app被kill,但是还存在等待中的任务A;第二次重新启动,先创建一个新的任务B,Aria会自动把B放进等待队列中,这时再次创建任务A,会导致重复下载,进度错乱的问题;本版本已修复这个问题
+ v_3.3.11 + v_3.3.11

@ -31,6 +31,12 @@ Aria有以下特点:
compile 'com.arialyy.aria:aria-core:3.3.13' compile 'com.arialyy.aria:aria-core:3.3.13'
annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.13' annotationProcessor 'com.arialyy.aria:aria-compiler:3.3.13'
``` ```
如果出现android support,请将 `compile 'com.arialyy.aria:aria-core:3.3.13'`替换为
```
compile('com.arialyy.aria:<last-version>'){
exclude group: 'com.android.support'
}
```
如果你使用的是kotlin,请使用kotlin官方提供的方法配置apt,[kotlin kapt官方配置传送门](https://www.kotlincn.net/docs/reference/kapt.html) 如果你使用的是kotlin,请使用kotlin官方提供的方法配置apt,[kotlin kapt官方配置传送门](https://www.kotlincn.net/docs/reference/kapt.html)
*** ***
@ -97,12 +103,10 @@ protected void onCreate(Bundle savedInstanceState) {
### [更多说明,见WIKI](https://github.com/AriaLyy/Aria/wiki) ### [更多说明,见WIKI](https://github.com/AriaLyy/Aria/wiki)
### 版本日志 ### 版本日志
+ v_3.3.11 + v_3.3.13
- 添加进度更新间隔api,在`aria_config.xml`配置`<updateInterval value="1000"/>`或在代码中调用 - 添加`@Download.onWait、@Upload.onWait、@DownloadGroup.onWait`三个新注解,队列已经满了,继续创建新任务,任务处于等待中,将会执行被这三个注解标志的方法
`AriaManager.getInstance(AriaManager.APP).getDownloadConfig().setUpdateInterval(3000)`便可以改变进度刷新间隔 - app被kill,但是还存在等待中的任务A;第二次重新启动,先创建一个新的任务B,Aria会自动把B放进等待队列中,这时再次创建任务A,会导致重复下载,进度错乱的问题;本版本已修复这个问题
- 修复下载过程中kill进程可能出现的文件错误的问题 https://github.com/AriaLyy/Aria/issues/192
- 修复http上传的空指针问题 https://github.com/AriaLyy/Aria/issues/193
- 修复下载地址中含有`'`导致的崩溃问题 https://github.com/AriaLyy/Aria/issues/194
[更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md) [更多版本记录](https://github.com/AriaLyy/Aria/blob/master/DEV_LOG.md)

@ -38,7 +38,8 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
//private final String URL = "ftp://192.168.1.9:21/下载/AriaPrj.zip"; //private final String URL = "ftp://192.168.1.9:21/下载/AriaPrj.zip";
//private final String URL = "ftp://192.168.1.9:21/下载/[电影天堂www.dy2018.com]赛车总动员3BD中英双字.mp4"; //private final String URL = "ftp://192.168.1.9:21/下载/[电影天堂www.dy2018.com]赛车总动员3BD中英双字.mp4";
//private final String URL = "ftp://h:h@tv.dl1234.com:2199/付岩洞复仇者们05.mkv"; //private final String URL = "ftp://h:h@tv.dl1234.com:2199/付岩洞复仇者们05.mkv";
private final String URL = "ftp://z:z@dygod18.com:21211/[破晓电影www.poxiao.com]情遇曼哈顿HD国语中字.mkv"; //private final String URL = "ftp://z:z@dygod18.com:21211/[破晓电影www.poxiao.com]情遇曼哈顿HD国语中字.mkv";
private final String URL = "ftp://182.92.180.213:21/video/572fed5c2ad48_1024.jpg";
//private final String URL = "ftp://172.18.104.71:21/upload/AS.zip"; //private final String URL = "ftp://172.18.104.71:21/upload/AS.zip";
@Override protected void init(Bundle savedInstanceState) { @Override protected void init(Bundle savedInstanceState) {
@ -60,8 +61,8 @@ public class FtpDownloadActivity extends BaseActivity<ActivityFtpDownloadBinding
public void onClick(View view) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.start: case R.id.start:
Aria.download(this).loadFtp(URL, true).charSet("gbk") Aria.download(this).loadFtp(URL, true).charSet("utf-8")
//.login("lao", "123456") .login("sxf", "B34VdGsJ")
.setDownloadPath("/mnt/sdcard/").start(); .setDownloadPath("/mnt/sdcard/").start();
break; break;
case R.id.stop: case R.id.stop:

@ -27,15 +27,10 @@ import android.widget.RadioGroup;
import android.widget.Toast; import android.widget.Toast;
import butterknife.Bind; import butterknife.Bind;
import com.arialyy.annotations.Download; import com.arialyy.annotations.Download;
import com.arialyy.annotations.DownloadGroup;
import com.arialyy.aria.core.Aria; import com.arialyy.aria.core.Aria;
import com.arialyy.aria.core.common.RequestEnum;
import com.arialyy.aria.core.download.DownloadEntity;
import com.arialyy.aria.core.download.DownloadGroupTask;
import com.arialyy.aria.core.download.DownloadTarget; import com.arialyy.aria.core.download.DownloadTarget;
import com.arialyy.aria.core.download.DownloadTask; import com.arialyy.aria.core.download.DownloadTask;
import com.arialyy.aria.core.inf.IEntity; import com.arialyy.aria.core.inf.IEntity;
import com.arialyy.aria.util.ALog;
import com.arialyy.aria.util.CommonUtil; import com.arialyy.aria.util.CommonUtil;
import com.arialyy.frame.util.show.L; import com.arialyy.frame.util.show.L;
import com.arialyy.frame.util.show.T; import com.arialyy.frame.util.show.T;
@ -63,7 +58,8 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//"http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-"; //"http://ox.konsung.net:5555/ksdc-web/download/downloadFile/?fileName=ksdc_1.0.2.apk&rRange=0-";
//"http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/QQ_718.apk"; //"http://gdown.baidu.com/data/wisegame/0904344dee4a2d92/QQ_718.apk";
//"http://qudao.5535.cn/one/game.html?game=531&cpsuser=xiaoeryu2"; //"http://qudao.5535.cn/one/game.html?game=531&cpsuser=xiaoeryu2";
"https://bogoe-res.mytbz.com/tbzengsong/If You're Happy.mp3"; //"https://bogoe-res.mytbz.com/tbzengsong/If You're Happy.mp3";
"http://ozr0ucjs5.bkt.clouddn.com/51_box-104_20180131202610.apk";
@Bind(R.id.start) Button mStart; @Bind(R.id.start) Button mStart;
@Bind(R.id.stop) Button mStop; @Bind(R.id.stop) Button mStop;
@Bind(R.id.cancel) Button mCancel; @Bind(R.id.cancel) Button mCancel;
@ -177,12 +173,12 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
mCancel.setEnabled(false); mCancel.setEnabled(false);
setBtState(true); setBtState(true);
getBinding().setSpeed(""); getBinding().setSpeed("");
L.d(TAG, "path ==> " + task.getDownloadEntity().getDownloadPath());
L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getDownloadPath()))); L.d(TAG, "md5Code ==> " + CommonUtil.getFileMD5(new File(task.getDownloadPath())));
L.d(TAG, "data ==> " + Aria.download(this).getDownloadEntity(DOWNLOAD_URL)); L.d(TAG, "data ==> " + Aria.download(this).getDownloadEntity(DOWNLOAD_URL));
} }
@Download.onNoSupportBreakPoint @Download.onNoSupportBreakPoint public void onNoSupportBreakPoint(DownloadTask task) {
public void onNoSupportBreakPoint(DownloadTask task) {
T.showShort(SingleTaskActivity.this, "该下载链接不支持断点"); T.showShort(SingleTaskActivity.this, "该下载链接不支持断点");
} }
@ -225,8 +221,10 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//Aria.get(this).setLogLevel(ALog.LOG_CLOSE); //Aria.get(this).setLogLevel(ALog.LOG_CLOSE);
//Aria.download(this).load("aaaa.apk"); //Aria.download(this).load("aaaa.apk");
Map<String, String> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("User-Agent", "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 Mobile MQQBrowser/6.2 TBS/043722 Safari/537.36"); map.put("User-Agent",
map.put("Cookie", "BAIDUID=DFC7EF42C60AD1ACF0BA94389AA67F13:FG=1; H_WISE_SIDS=121192_104493_114745_121434_119046_100098_120212_121140_118882_118858_118850_118820_118792_121254_121534_121214_117588_117242_117431_119974_120597_121043_121422_120943_121175_121272_117552_120482_121013_119962_119145_120851_120841_120034_121325_116407_121109_120654_110085_120708; PSINO=7; BDORZ=AE84CDB3A529C0F8A2B9DCDD1D18B695"); "Mozilla/5.0 (Linux; Android 4.4.4; Nexus 5 Build/KTU84P; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 Mobile MQQBrowser/6.2 TBS/043722 Safari/537.36");
map.put("Cookie",
"BAIDUID=DFC7EF42C60AD1ACF0BA94389AA67F13:FG=1; H_WISE_SIDS=121192_104493_114745_121434_119046_100098_120212_121140_118882_118858_118850_118820_118792_121254_121534_121214_117588_117242_117431_119974_120597_121043_121422_120943_121175_121272_117552_120482_121013_119962_119145_120851_120841_120034_121325_116407_121109_120654_110085_120708; PSINO=7; BDORZ=AE84CDB3A529C0F8A2B9DCDD1D18B695");
Aria.download(SingleTaskActivity.this) Aria.download(SingleTaskActivity.this)
.load(DOWNLOAD_URL) .load(DOWNLOAD_URL)
//.addHeader("groupName", "value") //.addHeader("groupName", "value")
@ -234,8 +232,8 @@ public class SingleTaskActivity extends BaseActivity<ActivitySingleBinding> {
//.setRequestMode(RequestEnum.POST) //.setRequestMode(RequestEnum.POST)
.setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1.apk") .setDownloadPath(Environment.getExternalStorageDirectory().getPath() + "/ggsg1.apk")
.resetState() .resetState()
//.start(); .start();
.add(); //.add();
} }
@Override protected void onDestroy() { @Override protected void onDestroy() {

Loading…
Cancel
Save