最近在一个项目中需要用到FTP服务器来上传文件,并且需要实现断点续传的功能。功能很简单,但是中途遇到一点意外导致折腾了很久,服务器的人员在配置的时候我的账户没添加断点指令的权限。话不多说直接上代码了:
第一步写一个登陆服务器的类:
public boolean initFTPSetting(String FTPUrl, int FTPPort, String UserName, String UserPassword) {
this.FTPUrl = FTPUrl;
this.FTPPort = FTPPort;
this.UserName = UserName;
this.UserPassword = UserPassword;int reply;
try {
//1.要连接的FTP服务器Url,Port
ftpClient.connect(FTPUrl, FTPPort);//2.登陆FTP服务器
ftpClient.login(UserName, UserPassword);//3.看返回的值是不是230,如果是,表示登陆成功
reply = ftpClient.getReplyCode();
JLog.d("reply:" +reply);
if (!FTPReply.isPositiveCompletion(reply)) {
//断开
ftpClient.disconnect();
return false;
}return true;
} catch (SocketException e) {
JLog.e("initFTPSetting:" + e.toString());
return false;
} catch (IOException e) {
JLog.e("initFTPSetting:" + e.toString());
reture false}
}
接下来就是做一个上传文件的功能,我是先将文件压缩然后再上传的,然后将压缩包的路径传过去,文件的压缩代码,下次有时间再补上。多文件的上传已经断点没有试过,有兴趣的朋友可以试下。
public boolean uploadFile(String FilePath, String FileName, String RemotePath) {
if (!ftpClient.isConnected()) {
if (!initFTPSetting(FTPUrl, FTPPort, UserName, UserPassword)) {
return false;
}
}try {
FileInputStream fileInputStream;
//设置存储路径
ftpClient.makeDirectory(RemotePath);
ftpClient.changeWorkingDirectory(RemotePath);
//设置上传文件需要的一些基本信息
//ftpClient.setBufferSize(1024);
//ftpClient.setControlEncoding("UTF-8");
/*
设置服务器为被动接收方式。发送PASV命令后,服务器会返回自己开启的数据传输的端口,
等待客户端连接进行数据传输。返回的数据格式为:“227 Entering Passive
*/
ftpClient.enterLocalPassiveMode();
//设置传输数据的类型:二进制数据或ASCII
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//设置进度条监听
ftpClient.setCopyStreamListener(streamListener);//=========================
String remoteFileName = RemotePath+FileName;
FTPFile[] files = ftpClient.listFiles(new String(remoteFileName
.getBytes("GBK"), "iso-8859-1"));
//文件上传
if (files.length == 1) {
long remoteSize = files[0].getSize();
File f = new File(FilePath);
long localSize = f.length();
JLog.d("localSize" + localSize +" remoteSize"+remoteSize);
if (remoteSize == localSize) {
JLog.d("两个文件大小一样");
ftpClient.setCopyStreamListener(null);
ftpClient.logout();
ftpClient.disconnect();
return true;} else if (remoteSize < localSize) {
JLog.d("remoteSize < localSize");
fileInputStream = new FileInputStream(FilePath);
if(fileInputStream.skip(remoteSize)==remoteSize){
totalsize = fileInputStream.available();
ftpClient.setRestartOffset(remoteSize);
upload_sise = remoteSize;
JLog.d("112 start storeFile :" +ftpClient.getRestartOffset());
if(ftpClient.storeFile(remoteFileName, fileInputStream)){
JLog.d("断点成功");
fileInputStream.close();
ftpClient.setCopyStreamListener(null);
ftpClient.logout();
ftpClient.disconnect();
return true;
}
if(!FTPReply.isPositiveIntermediate(ftpClient.getReplyCode())){
JLog.d("ftpClient.getReplyCode() "+ ftpClient.getReplyCode()
+ "FTP.getReplyString() :"+ftpClient.getReplyString());
}
}
}JLog.d("断点失败 开始新任务");
if(ftpClient.deleteFile(remoteFileName)){
JLog.d("delete success :" + remoteFileName);
}else {
JLog.d("delete failed :" + remoteFileName);
JLog.d("ftpClient.getReplyCode() "+ ftpClient.getReplyCode()
+ "FTP.getReplyString() :"+ftpClient.getReplyString());
}
}
fileInputStream = new FileInputStream(FilePath);
totalsize = fileInputStream.available();
JLog.d("start storeFile");
ftpClient.storeFile(FileName, fileInputStream);
//退出登陆FTP,关闭ftpCLient的连接
ftpClient.setCopyStreamListener(null);
ftpClient.logout();
ftpClient.disconnect();
fileInputStream.close();
return true;
} catch (IOException e) {
ftpClient.setCopyStreamListener(null);
return false;
}finally {
if(ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch(IOException ioe) {
// do nothing
}
}
}
}
在上传的过程还有一个设置监听,里面会有一个回调,将上传的进度返回:
CopyStreamListener streamListener = new CopyStreamListener() {
@Override
public void bytesTransferred(CopyStreamEvent copyStreamEvent) {
//totalsize = copyStreamEvent.getTotalBytesTransferred();
JLog.d("bytesTransferred :" + copyStreamEvent.getStreamSize());
}@Override
public void bytesTransferred(long l, int i, long l1) {
inc = ( l*100)/ totalsize;
if ((int)inc == pre_inc){
return;
}
pre_inc = (int)inc;
JLog.d("upload progress = " +inc +" %");
}
};
简单实用,搞定!