Android使用FTP实现断点续传
断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度。
我们都知道Android下使用HTTP实现断点续传很容易。因为我们在发送下载请求给服务器后,服务器会将该文件的信息返回给我们。同时我们也可以设置发送文件的起始位置,让服务器从该位置开始传输文件。
简单介绍一下FTP(File Transfer Protocol)文件传输协议。用于Internet上的控制文件的双向传输。在FTP的使用当中,用户经常遇到两个概念:”下载”(Download)和”上传”(Upload)。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。
FTP没有所谓的头文件,刚接触到还是有点雾水的,不知从何下手。但是查询一下资料后,觉得还是挺简单的,只需要一个指令。多说无益,给大家举个栗子- -、
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
try {
try {
ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
ftpClient.setControlEncoding("iso-8859-1");
} catch (Exception e) {
mHandler.sendEmptyMessage(DOWNLOAD_FAILED);
return;
}
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
return;
if (ftpClient.login(ftpUser, ftpPwd)) {
// 设置被动模式
ftpClient.enterLocalPassiveMode();
// 设置以二进制方式传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// 检查远程文件是否存在
FTPFile[] files = ftpClient.listFiles(new String(
ftpFileName.getBytes("GBK"), "iso-8859-1"));
int per = (int) (files[0].getSize() / 100);
FileOutputStream output = null;
InputStream input = null;
long localSize = 0L;
if (files.length == 0) {// 文件不存在,下载失败
mHandler.sendEmptyMessage(DOWNLOAD_FAILED);
return;
} else {// 开始下载
File file = new File(strLocalFile);
if (file.exists()) {// 存在,开始续传
localSize = file.length();
if (localSize > files[0].getSize()) {// 下载完成
mHandler.sendEmptyMessage(DOWNLOAD_SUCCESS);
return;
}
// 从本地文件上续传
output = new FileOutputStream(file, true);
// 将文件指向已下载的位置
ftpClient.setRestartOffset(localSize);
input = ftpClient.retrieveFileStream(new String(
ftpFileName.getBytes("GBK"), "iso-8859-1"));
progress = (int) (localSize / per);
mHandler.sendEmptyMessage(DOWNLOAD_UPDATE);
} else {// 直接下载
output = new FileOutputStream(file);
input = ftpClient.retrieveFileStream(new String(
ftpFileName.getBytes("GBK"), "iso-8859-1"));
mHandler.sendEmptyMessage(DOWNLOAD_START);
}
if (output == null || input == null) {
mHandler.sendEmptyMessage(DOWNLOAD_FAILED);
return;
}
byte[] bytes = new byte[1024];
int c;
while ((c = input.read(bytes)) != -1) {
if (isBreak) {
Log.i("xxx", "已停止下载!");
mHandler.sendEmptyMessage(DOWNLOAD_STOP);
break;
}
output.write(bytes, 0, c);
localSize += c;
long nowProcess = localSize / per;
if (nowProcess > progress) {
progress = nowProcess;
if (progress % 1 == 0) {
Log.i("xxx", "下载进度:" + progress);
}
mHandler.sendEmptyMessage(DOWNLOAD_UPDATE);
}
}
input.close();
output.close();
if (c <= 0) {// 下载完成
mHandler.sendEmptyMessage(DOWNLOAD_SUCCESS);
} else {
mHandler.sendEmptyMessage(DOWNLOAD_STOP);
}
}
}
} catch (Exception e) {
try {
ftpClient.disconnect();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
};
下面说一下使用FTP具体流程以及注意事项。
1. FTP的连接以及下载操作必须放在子线程中
2. ftpClient.setControlEncoding(“iso-8859-1”)设置字符编码,防止出现中文乱码现象
3. 获取本地已下载文件大小,然后使用ftpClient.setRestartOffset(localSize),可以开始断点续传了
FTP实现断点续传就这么简单完成了,逃。
ps:我使用jar包是Apache的commons-net。实现FTP断点续传,服务端的FTP也得支持断点续传的指令。 pps:功力有限,若有什么错误,请不吝赐教,谢谢