From c1b1cc139050dfd0f7862c8e3c22c290bcb33550 Mon Sep 17 00:00:00 2001 From: laoyuyu <511455842@qq.com> Date: Sat, 2 Nov 2019 10:58:49 +0800 Subject: [PATCH] fix bug https://github.com/AriaLyy/Aria/issues/493 --- FtpComponent/build.gradle | 1 - .../arialyy/aria/ftp/AbsFtpInfoThread.java | 2 +- .../arialyy/aria/ftp/FtpRecordAdapter.java | 13 +- FtpComponent/src/main/res/values/strings.xml | 3 - .../arialyy/aria/http/HttpRecordAdapter.java | 13 +- .../http/download/HttpDLoaderAdapter.java | 6 +- .../http/download/HttpDThreadTaskAdapter.java | 6 +- HttpComponent/src/main/res/values/strings.xml | 3 - .../com/arialyy/aria/m3u8/M3U8InfoThread.java | 2 +- .../aria/m3u8/live/M3U8LiveLoader.java | 2 +- .../arialyy/aria/m3u8/vod/M3U8VodLoader.java | 2 +- M3U8Component/src/main/res/values/strings.xml | 3 - .../aria/core/common/RecordHandler.java | 4 +- .../aria/core/common/RecordHelper.java | 41 ++++++ .../arialyy/aria/core/task/ThreadTask.java | 4 +- .../java/com/arialyy/aria/util/ErrorHelp.java | 2 +- .../java/com/arialyy/aria/util/FileUtil.java | 25 ++-- .../src/main/res/values/strings.xml | 3 - SFtpComponent/.gitignore | 1 + SFtpComponent/build.gradle | 33 +++++ SFtpComponent/consumer-rules.pro | 0 SFtpComponent/proguard-rules.pro | 21 +++ SFtpComponent/src/main/AndroidManifest.xml | 2 + .../arialyy/aria/sftp/AbsSFtpInfoThread.java | 58 ++++++++ .../java/com/arialyy/aria/sftp/SFtpLogin.java | 125 ++++++++++++++++++ app/src/main/assets/aria_config.xml | 2 +- .../core/download/HttpDownloadModule.java | 2 +- .../java/com/arialyy/simple/util/AppUtil.java | 2 +- settings.gradle | 2 +- 29 files changed, 331 insertions(+), 52 deletions(-) delete mode 100644 FtpComponent/src/main/res/values/strings.xml delete mode 100644 HttpComponent/src/main/res/values/strings.xml delete mode 100644 M3U8Component/src/main/res/values/strings.xml delete mode 100644 PublicComponent/src/main/res/values/strings.xml create mode 100644 SFtpComponent/.gitignore create mode 100644 SFtpComponent/build.gradle create mode 100644 SFtpComponent/consumer-rules.pro create mode 100644 SFtpComponent/proguard-rules.pro create mode 100644 SFtpComponent/src/main/AndroidManifest.xml create mode 100644 SFtpComponent/src/main/java/com/arialyy/aria/sftp/AbsSFtpInfoThread.java create mode 100644 SFtpComponent/src/main/java/com/arialyy/aria/sftp/SFtpLogin.java diff --git a/FtpComponent/build.gradle b/FtpComponent/build.gradle index 7974c103..10b1fbb7 100644 --- a/FtpComponent/build.gradle +++ b/FtpComponent/build.gradle @@ -27,7 +27,6 @@ dependencies { implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}" -// implementation project(path: ':AriaFtpPlug') implementation project(path: ':PublicComponent') } diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoThread.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoThread.java index 87f63342..468e6035 100644 --- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoThread.java +++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/AbsFtpInfoThread.java @@ -53,7 +53,7 @@ import javax.net.ssl.SSLContext; public abstract class AbsFtpInfoThread> implements Runnable { - private final String TAG = "AbsFtpInfoThread"; + private final String TAG = CommonUtil.getClassName(getClass()); protected ENTITY mEntity; protected TASK_WRAPPER mTaskWrapper; protected FtpTaskOption mTaskOption; diff --git a/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java b/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java index 83227543..47debcd6 100644 --- a/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java +++ b/FtpComponent/src/main/java/com/arialyy/aria/ftp/FtpRecordAdapter.java @@ -21,9 +21,8 @@ import com.arialyy.aria.core.common.AbsRecordHandlerAdapter; import com.arialyy.aria.core.common.RecordHelper; import com.arialyy.aria.core.config.Configuration; import com.arialyy.aria.core.download.DownloadEntity; -import com.arialyy.aria.core.common.AbsNormalEntity; -import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.inf.IRecordHandler; +import com.arialyy.aria.core.wrapper.AbsTaskWrapper; import com.arialyy.aria.core.wrapper.ITaskWrapper; import com.arialyy.aria.util.RecordUtil; import java.util.ArrayList; @@ -40,8 +39,12 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter { @Override public void handlerTaskRecord(TaskRecord record) { RecordHelper helper = new RecordHelper(getWrapper(), record); - if (record.isBlock) { - helper.handleBlockRecord(); + if (getWrapper().isSupportBP()) { + if (record.isBlock) { + helper.handleBlockRecord(); + } else { + helper.handleMutilRecord(); + } } else if (record.threadNum == 1) { helper.handleSingleThreadRecord(); } @@ -104,6 +107,4 @@ public class FtpRecordAdapter extends AbsRecordHandlerAdapter { return 1; } } - - } diff --git a/FtpComponent/src/main/res/values/strings.xml b/FtpComponent/src/main/res/values/strings.xml deleted file mode 100644 index 08862ffd..00000000 --- a/FtpComponent/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - AriaFtpComponent - diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java index 311ec0ed..88daeb7f 100644 --- a/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java +++ b/HttpComponent/src/main/java/com/arialyy/aria/http/HttpRecordAdapter.java @@ -38,15 +38,19 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter { @Override public void onPre() { super.onPre(); - if (getWrapper().getRequestType() == ITaskWrapper.U_HTTP){ + if (getWrapper().getRequestType() == ITaskWrapper.U_HTTP) { RecordUtil.delTaskRecord(getEntity().getFilePath(), IRecordHandler.TYPE_UPLOAD); } } @Override public void handlerTaskRecord(TaskRecord record) { RecordHelper helper = new RecordHelper(getWrapper(), record); - if (record.isBlock) { - helper.handleBlockRecord(); + if (getWrapper().isSupportBP()) { + if (record.isBlock) { + helper.handleBlockRecord(); + } else { + helper.handleMutilRecord(); + } } else if (!getWrapper().isSupportBP()) { helper.handleNoSupportBPRecord(); } else { @@ -81,7 +85,8 @@ public class HttpRecordAdapter extends AbsRecordHandlerAdapter { record.threadNum = threadNum; int requestType = getWrapper().getRequestType(); - if (requestType == ITaskWrapper.D_FTP || requestType == ITaskWrapper.D_FTP_DIR) { + if (requestType == ITaskWrapper.D_FTP || requestType == ITaskWrapper.D_FTP_DIR + || requestType == ITaskWrapper.D_HTTP || requestType == ITaskWrapper.DG_HTTP) { record.isBlock = threadNum > 1 && Configuration.getInstance().downloadCfg.isUseBlock(); // 线程数为1,或者使用了分块,则认为是使用动态长度文件 record.isOpenDynamicFile = threadNum == 1 || record.isBlock; diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java index 442b9816..0b5ed415 100644 --- a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java +++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDLoaderAdapter.java @@ -28,6 +28,7 @@ import com.arialyy.aria.core.wrapper.ITaskWrapper; import com.arialyy.aria.http.HttpRecordAdapter; 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; @@ -43,16 +44,15 @@ final class HttpDLoaderAdapter extends AbsNormalLoaderAdapter { @Override public boolean handleNewTask(TaskRecord record, int totalThreadNum) { if (!record.isBlock) { if (getTempFile().exists()) { - getTempFile().delete(); + FileUtil.deleteFile(getTempFile()); } - //CommonUtil.createFile(mTempFile.getPath()); } else { for (int i = 0; i < totalThreadNum; i++) { File blockFile = new File(String.format(IRecordHandler.SUB_PATH, getTempFile().getPath(), i)); if (blockFile.exists()) { ALog.d(TAG, String.format("分块【%s】已经存在,将删除该分块", i)); - blockFile.delete(); + FileUtil.deleteFile(blockFile); } } } diff --git a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java index bab8b614..e69ca84e 100644 --- a/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java +++ b/HttpComponent/src/main/java/com/arialyy/aria/http/download/HttpDThreadTaskAdapter.java @@ -15,13 +15,13 @@ */ package com.arialyy.aria.http.download; +import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.core.common.SubThreadConfig; import com.arialyy.aria.core.download.DTaskWrapper; import com.arialyy.aria.exception.AriaIOException; import com.arialyy.aria.exception.TaskException; import com.arialyy.aria.http.BaseHttpThreadTaskAdapter; import com.arialyy.aria.http.ConnectionHelp; -import com.arialyy.aria.core.common.RequestEnum; import com.arialyy.aria.util.ALog; import com.arialyy.aria.util.BufferedRandomAccessFile; import java.io.BufferedInputStream; @@ -123,6 +123,10 @@ final class HttpDThreadTaskAdapter extends BaseHttpThreadTaskAdapter { fail(new TaskException(TAG, String.format("任务【%s】下载失败,filePath: %s, url: %s", getFileName(), getEntity().getFilePath(), getEntity().getUrl()), e), true); + } catch (ArrayIndexOutOfBoundsException e) { + fail(new TaskException(TAG, + String.format("任务【%s】下载失败,filePath: %s, url: %s", getFileName(), + getEntity().getFilePath(), getEntity().getUrl()), e), false); } catch (Exception e) { fail(new TaskException(TAG, String.format("任务【%s】下载失败,filePath: %s, url: %s", getFileName(), diff --git a/HttpComponent/src/main/res/values/strings.xml b/HttpComponent/src/main/res/values/strings.xml deleted file mode 100644 index c76105c3..00000000 --- a/HttpComponent/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - HttpComponent - diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java index d4e637be..45be0b66 100644 --- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java +++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/M3U8InfoThread.java @@ -355,7 +355,7 @@ final public class M3U8InfoThread implements Runnable { File keyF = new File(info.keyPath); if (!keyF.exists()) { ALog.d(TAG, "密钥不存在,下载密钥"); - FileUtil.createFile(keyF.getPath()); + FileUtil.createFile(keyF); } else { return; } diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java index e7d7928d..297e5322 100644 --- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java +++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/live/M3U8LiveLoader.java @@ -150,7 +150,7 @@ public class M3U8LiveLoader extends BaseM3U8Loader { config.stateHandler = mStateHandler; if (!config.tempFile.exists()) { - FileUtil.createFile(config.tempFile.getPath()); + FileUtil.createFile(config.tempFile); } ThreadTask threadTask = new ThreadTask(config); M3U8ThreadTaskAdapter adapter = new M3U8ThreadTaskAdapter(config); diff --git a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java index 5038c097..19211a57 100644 --- a/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java +++ b/M3U8Component/src/main/java/com/arialyy/aria/m3u8/vod/M3U8VodLoader.java @@ -434,7 +434,7 @@ public class M3U8VodLoader extends BaseM3U8Loader { config.stateHandler = mStateHandler; config.peerIndex = index; if (!config.tempFile.exists()) { - FileUtil.createFile(config.tempFile.getPath()); + FileUtil.createFile(config.tempFile); } ThreadTask threadTask = new ThreadTask(config); M3U8ThreadTaskAdapter adapter = new M3U8ThreadTaskAdapter(config); diff --git a/M3U8Component/src/main/res/values/strings.xml b/M3U8Component/src/main/res/values/strings.xml deleted file mode 100644 index bd8f4556..00000000 --- a/M3U8Component/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - M3U8Component - diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java index 490715bb..bbdf78bf 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHandler.java @@ -86,8 +86,8 @@ public class RecordHandler implements IRecordHandler { mTaskRecord.threadNum = mAdapter.initTaskThreadNum(); initRecord(false); } - mAdapter.handlerTaskRecord(mTaskRecord); } + mAdapter.handlerTaskRecord(mTaskRecord); } saveRecord(); return mTaskRecord; @@ -145,7 +145,7 @@ public class RecordHandler implements IRecordHandler { } mTaskRecord.threadRecords.add(tRecord); } - mConfigFile.delete(); + FileUtil.deleteFile(mConfigFile); } } diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java index a3edd328..a6d8d157 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/common/RecordHelper.java @@ -20,7 +20,10 @@ import com.arialyy.aria.core.ThreadRecord; import com.arialyy.aria.core.inf.IRecordHandler; import com.arialyy.aria.core.wrapper.AbsTaskWrapper; 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; /** * 任务记录帮助类,用于处理统一的逻辑 @@ -39,6 +42,44 @@ public class RecordHelper { mTaskRecord = record; } + /** + * 处理非分块的,多线程任务 + */ + public void handleMutilRecord() { + // 默认线程分块长度 + long blockSize = mWrapper.getEntity().getFileSize() / mTaskRecord.threadRecords.size(); + File temp = new File(mTaskRecord.filePath); + boolean fileExists = false; + if (!temp.exists()) { + BufferedRandomAccessFile tempFile = null; + try { + tempFile = new BufferedRandomAccessFile(temp, "rw"); + tempFile.setLength(mWrapper.getEntity().getFileSize()); + } catch (IOException e) { + e.printStackTrace(); + } + + } else { + fileExists = true; + } + // 处理文件被删除的情况 + if (fileExists) { + for (int i = 0; i < mTaskRecord.threadNum; i++) { + long startL = i * blockSize, endL = (i + 1) * blockSize; + ThreadRecord tr = mTaskRecord.threadRecords.get(i); + tr.startLocation = startL; + tr.isComplete = false; + + //最后一个线程的结束位置即为文件的总长度 + if (tr.threadId == (mTaskRecord.threadNum - 1)) { + endL = mWrapper.getEntity().getFileSize(); + } + tr.endLocation = endL; + } + } + mWrapper.setNewTask(false); + } + /** * 处理分块任务的记录,分块文件(blockFileLen)长度必须需要小于等于线程区间(threadRectLen)的长度 */ diff --git a/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java b/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java index 464b9af6..23722c8b 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/core/task/ThreadTask.java @@ -367,8 +367,8 @@ public class ThreadTask implements IThreadTask, IThreadTaskObserver { || isNotNetRetry) && !isBreak()) { ALog.w(TAG, String.format("ts切片【%s】正在重试", getFileName())); mFailTimes++; - mConfig.tempFile.delete(); - FileUtil.createFile(mConfig.tempFile.getPath()); + FileUtil.deleteFile(mConfig.tempFile); + FileUtil.createFile(mConfig.tempFile); ThreadTaskManager.getInstance().retryThread(this); } else { sendFailMsg(null); diff --git a/PublicComponent/src/main/java/com/arialyy/aria/util/ErrorHelp.java b/PublicComponent/src/main/java/com/arialyy/aria/util/ErrorHelp.java index a89b933e..c0fb0f11 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/util/ErrorHelp.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/util/ErrorHelp.java @@ -79,7 +79,7 @@ public class ErrorHelp { try { File file = new File(getLogPath()); if (!file.exists()) { - FileUtil.createFile(file.getPath()); + FileUtil.createFile(file); } writer = new PrintWriter(new FileWriter(file.getPath(), true)); writer.append(stringBuffer); diff --git a/PublicComponent/src/main/java/com/arialyy/aria/util/FileUtil.java b/PublicComponent/src/main/java/com/arialyy/aria/util/FileUtil.java index 424c4679..4b1593ba 100644 --- a/PublicComponent/src/main/java/com/arialyy/aria/util/FileUtil.java +++ b/PublicComponent/src/main/java/com/arialyy/aria/util/FileUtil.java @@ -86,22 +86,23 @@ public class FileUtil { ALog.e(TAG, "文件路径不能为null"); return false; } - File file = new File(path); + return createFile(new File(path)); + } + + /** + * 创建文件 当文件不存在的时候就创建一个文件。 如果文件存在,先删除原文件,然后重新创建一个新文件 + * + * @return {@code true} 创建成功、{@code false} 创建失败 + */ + public static boolean createFile(File file) { if (file.getParentFile() == null || !file.getParentFile().exists()) { ALog.d(TAG, "目标文件所在路径不存在,准备创建……"); if (!createDir(file.getParent())) { - ALog.d(TAG, "创建目录文件所在的目录失败!文件路径【" + path + "】"); - } - } - // 创建目标文件 - if (file.exists()) { - final File to = new File(file.getAbsolutePath() + System.currentTimeMillis()); - if (file.renameTo(to)) { - to.delete(); - } else { - file.delete(); + ALog.d(TAG, "创建目录文件所在的目录失败!文件路径【" + file.getPath() + "】"); } } + // 文件存在,删除文件 + deleteFile(file); try { if (file.createNewFile()) { //ALog.d(TAG, "创建文件成功:" + file.getAbsolutePath()); @@ -327,7 +328,7 @@ public class FileUtil { ALog.d(TAG, String.format("block = %s", block)); File subFile = new File(subPath); if (!subFile.exists()) { - subFile.createNewFile(); + createFile(subFile); } FileOutputStream fos = new FileOutputStream(subFile); FileChannel sfoc = fos.getChannel(); diff --git a/PublicComponent/src/main/res/values/strings.xml b/PublicComponent/src/main/res/values/strings.xml deleted file mode 100644 index 568a9247..00000000 --- a/PublicComponent/src/main/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - PublicComponent - diff --git a/SFtpComponent/.gitignore b/SFtpComponent/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/SFtpComponent/.gitignore @@ -0,0 +1 @@ +/build diff --git a/SFtpComponent/build.gradle b/SFtpComponent/build.gradle new file mode 100644 index 00000000..193b7be6 --- /dev/null +++ b/SFtpComponent/build.gradle @@ -0,0 +1,33 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + buildToolsVersion rootProject.ext.buildToolsVersion + + defaultConfig { + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode rootProject.ext.versionCode + versionName rootProject.ext.versionName + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + consumerProguardFiles 'consumer-rules.pro' + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + + implementation "androidx.appcompat:appcompat:${rootProject.ext.XAppcompatVersion}" + implementation "com.jcraft:jsch:0.1.55" + implementation "com.jcraft:jzlib:1.1.3" + implementation project(path: ':FtpComponent') + compile project(path: ':PublicComponent') +} diff --git a/SFtpComponent/consumer-rules.pro b/SFtpComponent/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/SFtpComponent/proguard-rules.pro b/SFtpComponent/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/SFtpComponent/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/SFtpComponent/src/main/AndroidManifest.xml b/SFtpComponent/src/main/AndroidManifest.xml new file mode 100644 index 00000000..02ef15d0 --- /dev/null +++ b/SFtpComponent/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + diff --git a/SFtpComponent/src/main/java/com/arialyy/aria/sftp/AbsSFtpInfoThread.java b/SFtpComponent/src/main/java/com/arialyy/aria/sftp/AbsSFtpInfoThread.java new file mode 100644 index 00000000..3ab60bf6 --- /dev/null +++ b/SFtpComponent/src/main/java/com/arialyy/aria/sftp/AbsSFtpInfoThread.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.sftp; + +import com.arialyy.aria.core.AriaConfig; +import com.arialyy.aria.core.common.AbsEntity; +import com.arialyy.aria.core.inf.OnFileInfoCallback; +import com.arialyy.aria.core.upload.UploadEntity; +import com.arialyy.aria.core.wrapper.AbsTaskWrapper; +import com.arialyy.aria.ftp.FtpTaskOption; +import com.arialyy.aria.util.CommonUtil; + +/** + * + * https://cloud.tencent.com/developer/article/1354612 + * @author lyy + */ +public class AbsSFtpInfoThread> + implements Runnable { + + private final String TAG = CommonUtil.getClassName(getClass()); + protected ENTITY mEntity; + protected TASK_WRAPPER mTaskWrapper; + protected FtpTaskOption mTaskOption; + private int mConnectTimeOut; + protected OnFileInfoCallback mCallback; + protected long mSize = 0; + protected String charSet = "UTF-8"; + private boolean isUpload = false; + + public AbsSFtpInfoThread(TASK_WRAPPER taskWrapper, OnFileInfoCallback callback) { + mTaskWrapper = taskWrapper; + mEntity = taskWrapper.getEntity(); + mTaskOption = (FtpTaskOption) taskWrapper.getTaskOption(); + mConnectTimeOut = AriaConfig.getInstance().getDConfig().getConnectTimeOut(); + mCallback = callback; + if (mEntity instanceof UploadEntity) { + isUpload = true; + } + } + + @Override public void run() { + + } +} diff --git a/SFtpComponent/src/main/java/com/arialyy/aria/sftp/SFtpLogin.java b/SFtpComponent/src/main/java/com/arialyy/aria/sftp/SFtpLogin.java new file mode 100644 index 00000000..6c8b638c --- /dev/null +++ b/SFtpComponent/src/main/java/com/arialyy/aria/sftp/SFtpLogin.java @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.arialyy.aria.sftp; + +import android.text.TextUtils; +import com.jcraft.jsch.JSch; +import com.jcraft.jsch.JSchException; +import com.jcraft.jsch.Session; +import java.util.Properties; + +/** + * sftp登录 + * + * @author lyy + */ +public class SFtpLogin { + + private String ip, userName, password; + private int port; + private Session session; + private boolean isLogin = false; + + private SFtpLogin() { + createClient(); + } + + /** + * 创建客户端 + */ + private void createClient() { + JSch jSch = new JSch(); + try { + if (TextUtils.isEmpty(userName)) { + session = jSch.getSession(userName, ip, port); + } else { + session = jSch.getSession(ip); + } + if (!TextUtils.isEmpty(password)) { + session.setPassword(password); + } + Properties config = new Properties(); + config.put("StrictHostKeyChecking", "no"); + session.setConfig(config);// 为Session对象设置properties + session.setTimeout(3000);// 设置超时 + isLogin = true; + } catch (JSchException e) { + e.printStackTrace(); + } + } + + /** + * 执行登录 + */ + public Session login() { + try { + session.connect(); // 通过Session建立连接 + } catch (JSchException e) { + e.printStackTrace(); + } + return session; + } + + /** + * 登出 + */ + public void logout() { + if (session != null) { + session.disconnect(); + } + isLogin = false; + } + + public static class Builder { + private String ip, userName, password; + private int port = 22; + + public Builder setIp(String ip) { + this.ip = ip; + return this; + } + + public Builder setUserName(String userName) { + this.userName = userName; + return this; + } + + public Builder setPassword(String password) { + this.password = password; + return this; + } + + public Builder setPort(int port) { + this.port = port; + return this; + } + + public SFtpLogin build() { + SFtpLogin login = new SFtpLogin(); + login.ip = ip; + login.userName = userName; + login.password = password; + login.port = port; + if (TextUtils.isEmpty(ip)) { + throw new IllegalArgumentException("ip不能为空"); + } + if (port < 0 || port > 65534) { + throw new IllegalArgumentException("端口错误"); + } + return login; + } + } +} diff --git a/app/src/main/assets/aria_config.xml b/app/src/main/assets/aria_config.xml index e4ea2d42..cb8d1c24 100644 --- a/app/src/main/assets/aria_config.xml +++ b/app/src/main/assets/aria_config.xml @@ -32,7 +32,7 @@ 3、只对新的多线程下载任务有效 4、只对多线程的任务有效 --> - +