commit
845800814f
@ -0,0 +1,198 @@ |
|||||||
|
/* |
||||||
|
* 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.core.common; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import android.util.Log; |
||||||
|
import com.arialyy.aria.core.AriaManager; |
||||||
|
import com.arialyy.aria.core.download.DownloadEntity; |
||||||
|
import com.arialyy.aria.core.download.DownloadGroupEntity; |
||||||
|
import com.arialyy.aria.core.inf.AbsEntity; |
||||||
|
import com.arialyy.aria.core.inf.AbsTaskEntity; |
||||||
|
import com.arialyy.aria.core.upload.UploadEntity; |
||||||
|
import java.io.IOException; |
||||||
|
import org.apache.commons.net.ftp.FTP; |
||||||
|
import org.apache.commons.net.ftp.FTPClient; |
||||||
|
import org.apache.commons.net.ftp.FTPFile; |
||||||
|
import org.apache.commons.net.ftp.FTPReply; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/7/25. |
||||||
|
* 获取ftp文件夹信息 |
||||||
|
*/ |
||||||
|
public abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> |
||||||
|
implements Runnable { |
||||||
|
|
||||||
|
private final String TAG = "AbsFtpInfoThread"; |
||||||
|
protected ENTITY mEntity; |
||||||
|
protected TASK_ENTITY mTaskEntity; |
||||||
|
private int mConnectTimeOut; |
||||||
|
protected OnFileInfoCallback mCallback; |
||||||
|
protected long mSize = 0; |
||||||
|
protected String mServerIp, mPort; |
||||||
|
protected String charSet = "UTF-8"; |
||||||
|
private boolean isUpload = false; |
||||||
|
|
||||||
|
public AbsFtpInfoThread(TASK_ENTITY taskEntity, OnFileInfoCallback callback) { |
||||||
|
mTaskEntity = taskEntity; |
||||||
|
mEntity = taskEntity.getEntity(); |
||||||
|
mConnectTimeOut = |
||||||
|
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getConnectTimeOut(); |
||||||
|
mCallback = callback; |
||||||
|
if (mEntity instanceof UploadEntity) { |
||||||
|
isUpload = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置请求的远程文件路径 |
||||||
|
* |
||||||
|
* @return 远程文件路径 |
||||||
|
*/ |
||||||
|
protected abstract String setRemotePath(); |
||||||
|
|
||||||
|
@Override public void run() { |
||||||
|
FTPClient client = null; |
||||||
|
try { |
||||||
|
client = createFtpClient(); |
||||||
|
if (client == null) return; |
||||||
|
String remotePath = |
||||||
|
new String(setRemotePath().getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET); |
||||||
|
FTPFile[] files = client.listFiles(remotePath); |
||||||
|
mSize = getFileSize(files, client, remotePath); |
||||||
|
int reply = client.getReplyCode(); |
||||||
|
if (!FTPReply.isPositiveCompletion(reply)) { |
||||||
|
if (isUpload) { |
||||||
|
//服务器上没有该文件路径,表示该任务为新的上传任务
|
||||||
|
mTaskEntity.isNewTask = true; |
||||||
|
} else { |
||||||
|
client.disconnect(); |
||||||
|
failDownload("获取文件信息错误,错误码为:" + reply); |
||||||
|
return; |
||||||
|
} |
||||||
|
} |
||||||
|
mTaskEntity.code = reply; |
||||||
|
if (mSize != 0 && !isUpload) { |
||||||
|
mEntity.setFileSize(mSize); |
||||||
|
} |
||||||
|
mEntity.update(); |
||||||
|
mTaskEntity.update(); |
||||||
|
onPreComplete(reply); |
||||||
|
} catch (IOException e) { |
||||||
|
failDownload(e.getMessage()); |
||||||
|
} finally { |
||||||
|
if (client != null) { |
||||||
|
try { |
||||||
|
client.disconnect(); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void start() { |
||||||
|
new Thread(this).start(); |
||||||
|
} |
||||||
|
|
||||||
|
protected void onPreComplete(int code) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 创建FTP客户端 |
||||||
|
*/ |
||||||
|
private FTPClient createFtpClient() throws IOException { |
||||||
|
String url = ""; |
||||||
|
if (mEntity instanceof DownloadEntity) { |
||||||
|
url = ((DownloadEntity) mEntity).getUrl(); |
||||||
|
} else if (mEntity instanceof UploadEntity) { |
||||||
|
url = ((UploadEntity) mEntity).getUrl(); |
||||||
|
} else if (mEntity instanceof DownloadGroupEntity) { |
||||||
|
url = mEntity.getKey(); |
||||||
|
} else { |
||||||
|
failDownload("未知实体"); |
||||||
|
Log.e(TAG, "未知实体"); |
||||||
|
return null; |
||||||
|
} |
||||||
|
String[] pp = url.split("/")[2].split(":"); |
||||||
|
mServerIp = pp[0]; |
||||||
|
mPort = pp[1]; |
||||||
|
FTPClient client = new FTPClient(); |
||||||
|
// 连接服务器
|
||||||
|
client.connect(mServerIp, Integer.parseInt(mPort)); |
||||||
|
if (!TextUtils.isEmpty(mTaskEntity.account)) { |
||||||
|
client.login(mTaskEntity.userName, mTaskEntity.userPw); |
||||||
|
} else { |
||||||
|
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account); |
||||||
|
} |
||||||
|
int reply = client.getReplyCode(); |
||||||
|
if (!FTPReply.isPositiveCompletion(reply)) { |
||||||
|
client.disconnect(); |
||||||
|
failDownload("无法连接到ftp服务器,错误码为:" + reply); |
||||||
|
return null; |
||||||
|
} |
||||||
|
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
|
||||||
|
charSet = "UTF-8"; |
||||||
|
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion( |
||||||
|
client.sendCommand("OPTS UTF8", "ON"))) { |
||||||
|
charSet = mTaskEntity.charSet; |
||||||
|
} |
||||||
|
client.setControlEncoding(charSet); |
||||||
|
client.setDataTimeout(10 * 1000); |
||||||
|
client.enterLocalPassiveMode(); |
||||||
|
client.setFileType(FTP.BINARY_FILE_TYPE); |
||||||
|
client.setControlKeepAliveTimeout(5); |
||||||
|
return client; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 遍历FTP服务器上对应文件或文件夹大小 |
||||||
|
* |
||||||
|
* @throws IOException 字符串编码转换错误 |
||||||
|
*/ |
||||||
|
private long getFileSize(FTPFile[] files, FTPClient client, String dirName) throws IOException { |
||||||
|
long size = 0; |
||||||
|
String path = dirName + "/"; |
||||||
|
for (FTPFile file : files) { |
||||||
|
if (file.isFile()) { |
||||||
|
size += file.getSize(); |
||||||
|
handleFile(path + file.getName(), file); |
||||||
|
} else { |
||||||
|
String remotePath = |
||||||
|
new String((path + file.getName()).getBytes(charSet), AbsFtpThreadTask.SERVER_CHARSET); |
||||||
|
size += getFileSize(client.listFiles(remotePath), client, path + file.getName()); |
||||||
|
} |
||||||
|
} |
||||||
|
return size; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 处理FTP文件信息 |
||||||
|
* |
||||||
|
* @param remotePath ftp服务器文件夹路径 |
||||||
|
* @param ftpFile ftp服务器上对应的文件 |
||||||
|
*/ |
||||||
|
protected void handleFile(String remotePath, FTPFile ftpFile) { |
||||||
|
} |
||||||
|
|
||||||
|
private void failDownload(String errorMsg) { |
||||||
|
Log.e(TAG, errorMsg); |
||||||
|
if (mCallback != null) { |
||||||
|
mCallback.onFail(mEntity.getKey(), errorMsg); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
/* |
||||||
|
* 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.core.common; |
||||||
|
|
||||||
|
import android.text.TextUtils; |
||||||
|
import com.arialyy.aria.core.inf.AbsNormalEntity; |
||||||
|
import com.arialyy.aria.core.inf.AbsTaskEntity; |
||||||
|
import com.arialyy.aria.core.inf.IEventListener; |
||||||
|
import java.io.IOException; |
||||||
|
import org.apache.commons.net.ftp.FTP; |
||||||
|
import org.apache.commons.net.ftp.FTPClient; |
||||||
|
import org.apache.commons.net.ftp.FTPReply; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2017/9/26. |
||||||
|
* FTP单任务父类 |
||||||
|
*/ |
||||||
|
public abstract class AbsFtpThreadTask<ENTITY extends AbsNormalEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> |
||||||
|
extends AbsThreadTask<ENTITY, TASK_ENTITY> { |
||||||
|
protected String charSet, serverIp, port; |
||||||
|
/** |
||||||
|
* FTP 服务器编码 |
||||||
|
*/ |
||||||
|
public static String SERVER_CHARSET = "ISO-8859-1"; |
||||||
|
|
||||||
|
protected AbsFtpThreadTask(StateConstance constance, IEventListener listener, |
||||||
|
SubThreadConfig<TASK_ENTITY> info) { |
||||||
|
super(constance, listener, info); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 构建FTP客户端 |
||||||
|
*/ |
||||||
|
protected FTPClient createClient() throws IOException { |
||||||
|
String url = mEntity.getUrl(); |
||||||
|
String[] pp = url.split("/")[2].split(":"); |
||||||
|
serverIp = pp[0]; |
||||||
|
port = pp[1]; |
||||||
|
FTPClient client = new FTPClient(); |
||||||
|
// 连接服务器
|
||||||
|
client.connect(serverIp, Integer.parseInt(port)); |
||||||
|
if (!TextUtils.isEmpty(mTaskEntity.account)) { |
||||||
|
client.login(mTaskEntity.userName, mTaskEntity.userPw); |
||||||
|
} else { |
||||||
|
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account); |
||||||
|
} |
||||||
|
int reply = client.getReplyCode(); |
||||||
|
if (!FTPReply.isPositiveCompletion(reply)) { |
||||||
|
client.disconnect(); |
||||||
|
fail(STATE.CURRENT_LOCATION, "无法连接到ftp服务器,错误码为:" + reply, null); |
||||||
|
return null; |
||||||
|
} |
||||||
|
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
|
||||||
|
charSet = "UTF-8"; |
||||||
|
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion( |
||||||
|
client.sendCommand("OPTS UTF8", "ON"))) { |
||||||
|
charSet = mTaskEntity.charSet; |
||||||
|
} |
||||||
|
client.setControlEncoding(charSet); |
||||||
|
client.setDataTimeout(STATE.READ_TIME_OUT); |
||||||
|
client.enterLocalPassiveMode(); |
||||||
|
client.setFileType(FTP.BINARY_FILE_TYPE); |
||||||
|
client.setBufferSize(mBufSize); |
||||||
|
client.setControlKeepAliveTimeout(5); |
||||||
|
//client.setCopyStreamListener();
|
||||||
|
return client; |
||||||
|
} |
||||||
|
} |
@ -1,6 +1,6 @@ |
|||||||
package com.arialyy.aria.core.download.downloader; |
package com.arialyy.aria.core.common; |
||||||
|
|
||||||
interface OnFileInfoCallback { |
public interface OnFileInfoCallback { |
||||||
/** |
/** |
||||||
* 处理完成 |
* 处理完成 |
||||||
* |
* |
@ -1,155 +0,0 @@ |
|||||||
/* |
|
||||||
* 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.core.download.downloader; |
|
||||||
|
|
||||||
import android.text.TextUtils; |
|
||||||
import android.util.Log; |
|
||||||
import com.arialyy.aria.core.AriaManager; |
|
||||||
import com.arialyy.aria.core.common.AbsThreadTask; |
|
||||||
import com.arialyy.aria.core.inf.AbsEntity; |
|
||||||
import com.arialyy.aria.core.inf.AbsTaskEntity; |
|
||||||
import com.arialyy.aria.util.CommonUtil; |
|
||||||
import java.io.IOException; |
|
||||||
import org.apache.commons.net.ftp.FTP; |
|
||||||
import org.apache.commons.net.ftp.FTPClient; |
|
||||||
import org.apache.commons.net.ftp.FTPFile; |
|
||||||
import org.apache.commons.net.ftp.FTPReply; |
|
||||||
|
|
||||||
/** |
|
||||||
* Created by Aria.Lao on 2017/7/25. |
|
||||||
* 获取ftp文件夹信息 |
|
||||||
*/ |
|
||||||
abstract class AbsFtpInfoThread<ENTITY extends AbsEntity, TASK_ENTITY extends AbsTaskEntity<ENTITY>> |
|
||||||
implements Runnable { |
|
||||||
|
|
||||||
private final String TAG = "HttpFileInfoThread"; |
|
||||||
protected ENTITY mEntity; |
|
||||||
protected TASK_ENTITY mTaskEntity; |
|
||||||
private int mConnectTimeOut; |
|
||||||
private OnFileInfoCallback mCallback; |
|
||||||
protected long mSize = 0; |
|
||||||
|
|
||||||
AbsFtpInfoThread(TASK_ENTITY taskEntity, OnFileInfoCallback callback) { |
|
||||||
mTaskEntity = taskEntity; |
|
||||||
mEntity = taskEntity.getEntity(); |
|
||||||
mConnectTimeOut = |
|
||||||
AriaManager.getInstance(AriaManager.APP).getDownloadConfig().getConnectTimeOut(); |
|
||||||
mCallback = callback; |
|
||||||
} |
|
||||||
|
|
||||||
@Override public void run() { |
|
||||||
FTPClient client = null; |
|
||||||
try { |
|
||||||
String url = mTaskEntity.getEntity().getKey(); |
|
||||||
String[] pp = url.split("/")[2].split(":"); |
|
||||||
String serverIp = pp[0]; |
|
||||||
int port = Integer.parseInt(pp[1]); |
|
||||||
String remotePath = url.substring(url.indexOf(pp[1]) + pp[1].length(), url.length()); |
|
||||||
client = new FTPClient(); |
|
||||||
client.connect(serverIp, port); |
|
||||||
if (!TextUtils.isEmpty(mTaskEntity.account)) { |
|
||||||
client.login(mTaskEntity.userName, mTaskEntity.userPw); |
|
||||||
} else { |
|
||||||
client.login(mTaskEntity.userName, mTaskEntity.userPw, mTaskEntity.account); |
|
||||||
} |
|
||||||
int reply = client.getReplyCode(); |
|
||||||
if (!FTPReply.isPositiveCompletion(reply)) { |
|
||||||
client.disconnect(); |
|
||||||
failDownload("无法连接到ftp服务器,错误码为:" + reply); |
|
||||||
return; |
|
||||||
} |
|
||||||
client.setDataTimeout(mConnectTimeOut); |
|
||||||
String charSet = "UTF-8"; |
|
||||||
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码
|
|
||||||
if (!TextUtils.isEmpty(mTaskEntity.charSet) || !FTPReply.isPositiveCompletion( |
|
||||||
client.sendCommand("OPTS UTF8", "ON"))) { |
|
||||||
charSet = mTaskEntity.charSet; |
|
||||||
} |
|
||||||
client.setControlEncoding(charSet); |
|
||||||
client.enterLocalPassiveMode(); |
|
||||||
client.setFileType(FTP.BINARY_FILE_TYPE); |
|
||||||
FTPFile[] files = |
|
||||||
client.listFiles(new String(remotePath.getBytes(charSet), AbsThreadTask.SERVER_CHARSET)); |
|
||||||
mSize = getFileSize(files, client, remotePath); |
|
||||||
reply = client.getReplyCode(); |
|
||||||
if (!FTPReply.isPositiveCompletion(reply)) { |
|
||||||
client.disconnect(); |
|
||||||
failDownload("获取文件信息错误,错误码为:" + reply); |
|
||||||
return; |
|
||||||
} |
|
||||||
mTaskEntity.code = reply; |
|
||||||
onPreComplete(); |
|
||||||
mEntity.update(); |
|
||||||
mTaskEntity.update(); |
|
||||||
mCallback.onComplete(mEntity.getKey(), reply); |
|
||||||
} catch (IOException e) { |
|
||||||
failDownload(e.getMessage()); |
|
||||||
} finally { |
|
||||||
if (client != null) { |
|
||||||
try { |
|
||||||
client.disconnect(); |
|
||||||
} catch (IOException e) { |
|
||||||
e.printStackTrace(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void start() { |
|
||||||
new Thread(this).start(); |
|
||||||
} |
|
||||||
|
|
||||||
protected void onPreComplete() { |
|
||||||
|
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 遍历FTP服务器上对应文件或文件夹大小 |
|
||||||
* |
|
||||||
* @throws IOException |
|
||||||
*/ |
|
||||||
private long getFileSize(FTPFile[] files, FTPClient client, String dirName) throws IOException { |
|
||||||
long size = 0; |
|
||||||
String path = dirName + "/"; |
|
||||||
for (FTPFile file : files) { |
|
||||||
if (file.isFile()) { |
|
||||||
size += file.getSize(); |
|
||||||
handleFile(path + file.getName(), file); |
|
||||||
} else { |
|
||||||
size += getFileSize(client.listFiles( |
|
||||||
CommonUtil.strCharSetConvert(path + file.getName(), mTaskEntity.charSet)), client, |
|
||||||
path + file.getName()); |
|
||||||
} |
|
||||||
} |
|
||||||
return size; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 处理FTP文件信息 |
|
||||||
* |
|
||||||
* @param remotePath ftp服务器文件夹路径 |
|
||||||
* @param ftpFile ftp服务器上对应的文件 |
|
||||||
*/ |
|
||||||
void handleFile(String remotePath, FTPFile ftpFile) { |
|
||||||
} |
|
||||||
|
|
||||||
private void failDownload(String errorMsg) { |
|
||||||
Log.e(TAG, errorMsg); |
|
||||||
if (mCallback != null) { |
|
||||||
mCallback.onFail(mEntity.getKey(), errorMsg); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,74 @@ |
|||||||
|
/* |
||||||
|
* 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.core.upload.uploader; |
||||||
|
|
||||||
|
import android.support.annotation.NonNull; |
||||||
|
import com.arialyy.aria.util.BufferedRandomAccessFile; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by lyy on 2017/9/26. |
||||||
|
* BufferedRandomAccessFile 转 InputStream 适配器 |
||||||
|
*/ |
||||||
|
final class FtpFISAdapter extends InputStream { |
||||||
|
|
||||||
|
private BufferedRandomAccessFile mIs; |
||||||
|
private ProgressCallback mCallback; |
||||||
|
private int count; |
||||||
|
|
||||||
|
interface ProgressCallback { |
||||||
|
void onProgressCallback(byte[] buffer, int byteOffset, int byteCount) throws IOException; |
||||||
|
} |
||||||
|
|
||||||
|
FtpFISAdapter(@NonNull BufferedRandomAccessFile is, @NonNull ProgressCallback callback) { |
||||||
|
mIs = is; |
||||||
|
mCallback = callback; |
||||||
|
} |
||||||
|
|
||||||
|
FtpFISAdapter(@NonNull BufferedRandomAccessFile is) { |
||||||
|
mIs = is; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public void close() throws IOException { |
||||||
|
mIs.close(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public int read() throws IOException { |
||||||
|
return mIs.read(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override public int read(@NonNull byte[] buffer) throws IOException { |
||||||
|
count = mIs.read(buffer); |
||||||
|
if (mCallback != null) { |
||||||
|
mCallback.onProgressCallback(buffer, 0, count); |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public int read(@NonNull byte[] buffer, int byteOffset, int byteCount) |
||||||
|
throws IOException { |
||||||
|
count = mIs.read(buffer, byteOffset, byteCount); |
||||||
|
if (mCallback != null) { |
||||||
|
mCallback.onProgressCallback(buffer, byteOffset, byteCount); |
||||||
|
} |
||||||
|
return count; |
||||||
|
} |
||||||
|
|
||||||
|
@Override public long skip(long byteCount) throws IOException { |
||||||
|
return mIs.skipBytes((int) byteCount); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
/* |
||||||
|
* 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.core.upload.uploader; |
||||||
|
|
||||||
|
import com.arialyy.aria.core.common.AbsFtpInfoThread; |
||||||
|
import com.arialyy.aria.core.common.OnFileInfoCallback; |
||||||
|
import com.arialyy.aria.core.upload.UploadEntity; |
||||||
|
import com.arialyy.aria.core.upload.UploadTaskEntity; |
||||||
|
import com.arialyy.aria.util.CommonUtil; |
||||||
|
import java.io.File; |
||||||
|
import java.util.Properties; |
||||||
|
import org.apache.commons.net.ftp.FTPFile; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by Aria.Lao on 2017/9/26. |
||||||
|
* 单任务远程服务器文件信息 |
||||||
|
*/ |
||||||
|
class FtpFileInfoThread extends AbsFtpInfoThread<UploadEntity, UploadTaskEntity> { |
||||||
|
static final int CODE_COMPLETE = 0xab1; |
||||||
|
private boolean isComplete = false; |
||||||
|
|
||||||
|
FtpFileInfoThread(UploadTaskEntity taskEntity, OnFileInfoCallback callback) { |
||||||
|
super(taskEntity, callback); |
||||||
|
} |
||||||
|
|
||||||
|
@Override protected String setRemotePath() { |
||||||
|
String url = mEntity.getUrl(); |
||||||
|
return url.substring(url.indexOf(mPort) + mPort.length(), url.length()) |
||||||
|
+ "/" |
||||||
|
+ mEntity.getFileName(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 如果服务器的文件长度和本地上传文件的文件长度一致,则任务任务已完成。 |
||||||
|
* 否则重新修改保存的停止位置,这是因为outputStream是读不到服务器是否成功写入的。 |
||||||
|
* 而threadTask的保存的停止位置是File的InputStream的,所有就会导致两端停止位置不一致 |
||||||
|
* |
||||||
|
* @param remotePath ftp服务器文件夹路径 |
||||||
|
* @param ftpFile ftp服务器上对应的文件 |
||||||
|
*/ |
||||||
|
@Override protected void handleFile(String remotePath, FTPFile ftpFile) { |
||||||
|
super.handleFile(remotePath, ftpFile); |
||||||
|
if (ftpFile != null) { |
||||||
|
//远程文件已完成
|
||||||
|
if (ftpFile.getSize() == mEntity.getFileSize()) { |
||||||
|
isComplete = true; |
||||||
|
} else { |
||||||
|
File configFile = new File(CommonUtil.getFileConfigPath(false, mEntity.getFileName())); |
||||||
|
Properties pro = CommonUtil.loadConfig(configFile); |
||||||
|
String key = mEntity.getFileName() + "_record_" + 0; |
||||||
|
long oldRecord = Long.parseLong(pro.getProperty(key, "0")); |
||||||
|
if (oldRecord != 0) { |
||||||
|
//修改本地保存的停止地址为服务器上的真实地址
|
||||||
|
pro.setProperty(key, ftpFile.getSize() + ""); |
||||||
|
CommonUtil.saveConfig(configFile, pro); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override protected void onPreComplete(int code) { |
||||||
|
super.onPreComplete(code); |
||||||
|
mCallback.onComplete(mEntity.getKey(), isComplete ? CODE_COMPLETE : code); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,136 @@ |
|||||||
|
/* |
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one |
||||||
|
* or more contributor license agreements. See the NOTICE file |
||||||
|
* distributed with this work for additional information |
||||||
|
* regarding copyright ownership. The ASF licenses this file |
||||||
|
* to you 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.util; |
||||||
|
|
||||||
|
import android.content.Context; |
||||||
|
import android.net.ConnectivityManager; |
||||||
|
import android.net.NetworkInfo; |
||||||
|
import android.telephony.TelephonyManager; |
||||||
|
import android.text.TextUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* 跟网络相关的工具类 |
||||||
|
*/ |
||||||
|
public class NetUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* 没有网络 |
||||||
|
*/ |
||||||
|
public static final int NETWORK_TYPE_INVALID = 0; |
||||||
|
/** |
||||||
|
* wap网络 |
||||||
|
*/ |
||||||
|
public static final int NETWORK_TYPE_WAP = 1; |
||||||
|
/** |
||||||
|
* 2G网络 |
||||||
|
*/ |
||||||
|
public static final int NETWORK_TYPE_2G = 2; |
||||||
|
/** |
||||||
|
* 3G和3G以上网络,或统称为快速网络 |
||||||
|
*/ |
||||||
|
public static final int NETWORK_TYPE_3G = 3; |
||||||
|
/** |
||||||
|
* wifi网络 |
||||||
|
*/ |
||||||
|
public static final int NETWORK_TYPE_WIFI = 4; |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断网络是否连接 |
||||||
|
*/ |
||||||
|
public static boolean isConnected(Context context) { |
||||||
|
ConnectivityManager cm = |
||||||
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); |
||||||
|
NetworkInfo ni = cm.getActiveNetworkInfo(); |
||||||
|
return ni != null && ni.isConnectedOrConnecting(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否是wifi连接 |
||||||
|
*/ |
||||||
|
public static boolean isWifi(Context context) { |
||||||
|
return getNetWorkType(context) == NETWORK_TYPE_WIFI; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取网络状态,wifi,wap,2g,3g. |
||||||
|
* |
||||||
|
* @param context 上下文 |
||||||
|
* @return int 网络状态 {@link #NETWORK_TYPE_2G},{@link #NETWORK_TYPE_3G}, |
||||||
|
* {@link #NETWORK_TYPE_INVALID},{@link #NETWORK_TYPE_WAP},{@link #NETWORK_TYPE_WIFI} |
||||||
|
*/ |
||||||
|
public static int getNetWorkType(Context context) { |
||||||
|
int netWorkType = -1; |
||||||
|
ConnectivityManager manager = |
||||||
|
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); |
||||||
|
NetworkInfo networkInfo = manager.getActiveNetworkInfo(); |
||||||
|
if (networkInfo != null && networkInfo.isConnected()) { |
||||||
|
String type = networkInfo.getTypeName(); |
||||||
|
if (type.equalsIgnoreCase("WIFI")) { |
||||||
|
netWorkType = NETWORK_TYPE_WIFI; |
||||||
|
} else if (type.equalsIgnoreCase("MOBILE")) { |
||||||
|
String proxyHost = android.net.Proxy.getDefaultHost(); |
||||||
|
netWorkType = TextUtils.isEmpty(proxyHost) ? (isFastMobileNetwork(context) ? NETWORK_TYPE_3G |
||||||
|
: NETWORK_TYPE_2G) : NETWORK_TYPE_WAP; |
||||||
|
} |
||||||
|
} else { |
||||||
|
netWorkType = NETWORK_TYPE_INVALID; |
||||||
|
} |
||||||
|
return netWorkType; |
||||||
|
} |
||||||
|
|
||||||
|
private static boolean isFastMobileNetwork(Context context) { |
||||||
|
TelephonyManager telephonyManager = |
||||||
|
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); |
||||||
|
switch (telephonyManager.getNetworkType()) { |
||||||
|
case TelephonyManager.NETWORK_TYPE_1xRTT: |
||||||
|
return false; // ~ 50-100 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_CDMA: |
||||||
|
return false; // ~ 14-64 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EDGE: |
||||||
|
return false; // ~ 50-100 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EVDO_0: |
||||||
|
return true; // ~ 400-1000 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EVDO_A: |
||||||
|
return true; // ~ 600-1400 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_GPRS: |
||||||
|
return false; // ~ 100 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSDPA: |
||||||
|
return true; // ~ 2-14 Mbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSPA: |
||||||
|
return true; // ~ 700-1700 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSUPA: |
||||||
|
return true; // ~ 1-23 Mbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_UMTS: |
||||||
|
return true; // ~ 400-7000 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EHRPD: |
||||||
|
return true; // ~ 1-2 Mbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EVDO_B: |
||||||
|
return true; // ~ 5 Mbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSPAP: |
||||||
|
return true; // ~ 10-20 Mbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_IDEN: |
||||||
|
return false; // ~25 kbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_LTE: |
||||||
|
return true; // ~ 10+ Mbps
|
||||||
|
case TelephonyManager.NETWORK_TYPE_UNKNOWN: |
||||||
|
return false; |
||||||
|
default: |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,33 @@ |
|||||||
|
/* |
||||||
|
* 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 org.apache.commons.net.ftp; |
||||||
|
|
||||||
|
import org.apache.commons.net.io.CopyStreamListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by AriaL on 2017/9/26. |
||||||
|
* ftp 上传文件流事件监听 |
||||||
|
*/ |
||||||
|
public interface OnFtpInputStreamListener { |
||||||
|
/** |
||||||
|
* {@link CopyStreamListener#bytesTransferred(long, int, long)} |
||||||
|
* |
||||||
|
* @param totalBytesTransferred 已经上传的文件长度 |
||||||
|
* @param bytesTransferred 上传byte长度 |
||||||
|
*/ |
||||||
|
void onFtpInputStream(FTPClient client, long totalBytesTransferred, int bytesTransferred, |
||||||
|
long streamSize); |
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue