package cn.eason.util.common;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import org.apache.commons.net.PrintCommandListener;
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;
public class ContinueFTP {
private FTPClient ftpClient = newFTPClient();
public ContinueFTP(){
//设置将过程中使用到的命令输出到控制台
this.ftpClient.addProtocolCommandListener(newPrintCommandListener(new PrintWriter(System.out)));
}
public boolean connect(Stringhostname,int port,String username,Stringpassword)
throwsIOException {
//连接到FTP服务器
ftpClient.connect(hostname,port);
//如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode()))
{
if(ftpClient.login(username, password))
{
returntrue;
}
}
disconnect();
return false;
}
public DownloadStatusdownload(String remote,String local,String mode) throwsIOException{
//设置ftp传输方式
if(mode.equalsIgnoreCase("P")){
//PassiveMode传输
ftpClient.enterLocalPassiveMode();
}
else{
//ActiveMode传输
ftpClient.enterLocalActiveMode();
}
//设置以二进制流的方式传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//下载状态
DownloadStatus result;
//本地文件列表
File f =new File(local);
//检查远程文件是否存在
FTPFile[]files = ftpClient.listFiles(newString(remote.getBytes("GBK"),"iso-8859-1"));
if(files.length != 1){
System.out.println("远程文件不存在");
returnDownloadStatus.Remote_File_Noexist;
}
//获得远端文件大小
longlRemoteSize = files[0].getSize();
//构建输出对象
OutputStream ut = null ;
//本地存在文件,进行断点下载 ;不存在则新下载
if(f.exists()){
//构建输出对象
out = newFileOutputStream(f,true);
//本地文件大小
long localSize = f.length();
System.out.println("本地文件大小为:"+localSize);
//判定本地文件大小是否大于远程文件大小
if(localSize>= lRemoteSize){
System.out.println("本地文件大于远程文件,下载中止");
return DownloadStatus.Local_Bigger_Remote;
}
//否则进行断点续传,并记录状态
ftpClient.setRestartOffset(localSize); //该方法尝试把指针移动到远端文件的指定字节位置
InputStream in =ftpClient.retrieveFileStream(newString(remote.getBytes("GBK"),"iso-8859-1"));
byte[] bytes = newbyte[1024];
long step = lRemoteSize /100;
//存放下载进度
long process=localSize /step;
int c;
while((c = in.read(bytes))!=-1){
out.write(bytes,0,c);
localSize+=c;
long nowProcess = localSize /step;
if(nowProcess > process){
process =nowProcess;
if(process% 10 == 0)
System.out.println("下载进度:"+process);
//TODO更新文件下载进度,值存放在process变量中
}
}
//下载完成关闭输入输出流对象
in.close();
out.close();
boolean isDo =ftpClient.completePendingCommand();
if(isDo){
result =DownloadStatus.Download_From_Break_Success;
}else {
result =DownloadStatus.Download_From_Break_Failed;
}
}else{
out = new FileOutputStream(f);
InputStream in=ftpClient.retrieveFileStream(newString(remote.getBytes("GBK"),"iso-8859-1"));
byte[] bytes = newbyte[1024];
long step = lRemoteSize /100;
long process=0;
long localSize = 0L;
int c;
while((c = in.read(bytes))!=-1){
out.write(bytes, 0, c);
localSize+=c;
long nowProcess = localSize /step;
if(nowProcess > process){
process =nowProcess;
if(process% 10 == 0)
System.out.println("下载进度:"+process);
//TODO更新文件下载进度,值存放在process变量中
}
}
in.close();
out.close();
boolean upNewStatus =ftpClient.completePendingCommand();
if(upNewStatus){
result = DownloadStatus.Download_New_Success;
}else {
result = DownloadStatus.Download_New_Failed;
}
}
returnresult;
}
public UploadStatus upload(String local,Stringremote,String mode) throws IOException{
//设置PassiveMode传输
ftpClient.enterLocalPassiveMode();
//设置以二进制流的方式传输
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
UploadStatus result;
//对远程目录的处理
StringremoteFileName = remote;
if(remote.contains("/")){
remoteFileName =remote.substring(remote.lastIndexOf("/")+1);
String directory =remote.substring(0,remote.lastIndexOf("/")+1);
if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){
//如果远程目录不存在,则递归创建远程服务器目录
int start=0;
int end = 0;
if(directory.startsWith("/")){
start =1;
}else{
start =0;
}
end =directory.indexOf("/",start);
while(true){
StringsubDirectory = remote.substring(start,end);
if(!ftpClient.changeWorkingDirectory(subDirectory)){
if(ftpClient.makeDirectory(subDirectory)){
ftpClient.changeWorkingDirectory(subDirectory);
}else{
System.out.println("创建目录失败");
returnUploadStatus.Create_Directory_Fail;
}
}
start =end + 1;
end =directory.indexOf("/",start);
//检查所有目录是否创建完毕
if(end<= start){
break;
}
}
}
}
//检查远程是否存在文件
FTPFile[]files =ftpClient.listFiles(remoteFileName);
if(files.length == 1){
long remoteSize =files[0].getSize();
File f = newFile(local);
long localSize =f.length();
if(remoteSize==localSize){
returnUploadStatus.File_Exits;
}else if(remoteSize> localSize){
returnUploadStatus.Remote_Bigger_Local;
}
//尝试移动文件内读取指针,实现断点续传
InputStream is = newFileInputStream(f);
if(is.skip(remoteSize)==remoteSize){
ftpClient.setRestartOffset(remoteSize);
if(ftpClient.storeFile(remote,is)){
returnUploadStatus.Upload_From_Break_Success;
}
}
//如果断点续传没有成功,则删除服务器上文件,重新上传
if(!ftpClient.deleteFile(remoteFileName)){
returnUploadStatus.Delete_Remote_Faild;
}
is = newFileInputStream(f);
if(ftpClient.storeFile(remote, is)){
result =UploadStatus.Upload_New_File_Success;
}else{
result =UploadStatus.Upload_New_File_Failed;
}
is.close();
}else{
InputStream is = newFileInputStream(local);
if(ftpClient.storeFile(remoteFileName,is)){
result =UploadStatus.Upload_New_File_Success;
}else{
result =UploadStatus.Upload_New_File_Failed;
}
is.close();
}
returnresult;
}
publicvoid disconnect() throws IOException{
if(ftpClient.isConnected()){
ftpClient.disconnect();
}
}