做一个FTP的断点续传功能,FTP使用的是org.apache.commons.net.ftp.FTPClient
个人认为需要解决的问题有:
1、上传的时候暂停
2、找到服务器上是否已经存在文件
这两个问题解决了,断点续传也就差不多了
首先,怎么将上传的任务终止的问题
设置FTP的setCopyStreamListener,可以获取当前上传的进度,可以在这里中止
中止的方法:直接退出FTP ftp.logout();
ftp.setCopyStreamListener(new CopyStreamListener() {
@Override
public void bytesTransferred(long arg0, int arg1, long arg2) {
// TODO 符合某个条件的时候执行logout
ftp.logout();
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>@Override
<span style="white-space:pre"> </span>public void bytesTransferred(CopyStreamEvent arg0) {}
});
</pre><p></p><pre>
中止任务的问题解决了,那么再看第二个问题
FTP服务器可能会在一个用户下建立多个目录,比如按天保存上传的文件
这就需要遍历服务器上的目录
这里需要根据FTP服务器的目录结构来写,下面代码是遍历用户下多个目录中的所有文件
如果用户下面没有目录,可以只用一个循环,根据自己的情况修改
String str = path.substring(0, path.lastIndexOf("/")); // path上FTP服务器上的路径
if(path.endsWith("/")) { // 这个处理是获取到的FTP目录会以 / 结尾,不知道是不是所有都这样
str = str.substring(0, str.lastIndexOf("/"));
}
ftp.changeWorkingDirectory(str);
String[] files = ftp.listNames();
for(int i=0; i<files.length; i++) {
ftp.changeWorkingDirectory(str + "/" + files[i]);
FTPFile[] ftpFiles = ftp.listFiles();
for(int j=0; j<ftpFiles.length; j++) {
// 打印出文件大小和文件名字
Log.e("msg", "ftpFiles : " + ftpFiles[j].getSize() + ", " + ftpFiles[j].getName());
}
}
如果已经存在文件
FileInputStream in = new FileInputStream(new File(filePath));
if(in.skip(length) == length) { // 这个length是FTP上已经存在的文件的大小
ftp.setRestartOffset(length); // 设置文件内部指针
}
在最后,只要做一些FTP的其他设置
ftp.setBufferSize(MAX);
ftp.enterLocalPassiveMode();
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
设置完了后上传就好了
ftp.storeFile(fileName, in);
需要注意的是,如果FTP服务器上已经存在的文件,这个fileName需要和服务器上的name一样,才会续传
===================2015.01.12===============
做断点续传,不知道为什么,设置文件指针后上传会卡住,N...N久,完全不能接受!!
经过测试,应该是指定了文件读取的指针使流卡住了。
意外的发现,让流读取发生异常,再续传的时候就没问题
停止上传修改:
在logout的地方改为inputStream.close();,主动关闭流,发生异常,停止上传
要捕获异常,免得程序崩溃