package cn.ksource.core.ftp; 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; import cn.ksource.config.SysConfigConstants; import cn.ksource.core.util.ConvertUtil; public class FtpClient { public FTPClient ftpClient = new FTPClient(); public FtpClient() throws IOException, FtpConnectionException{ this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out))); String url = SysConfigConstants.FTP_URL; String port = SysConfigConstants.FTP_PORT; String username = SysConfigConstants.FTP_USERNAME; String password = SysConfigConstants.FTP_PASSWORD; if (!connect(url, ConvertUtil.obj2Integer(port), username, password)) { throw new FtpConnectionException("无法连接FTP服务器,在:" + url + ":"+port+",用户名/密码:"+username+" "+password); } } /** * java编程中用于连接到FTP服务器 * @param hostname 主机名 * @param port 端口 * @param username 用户名 * @param password 密码 * @return 是否连接成功 * @throws IOException */ public boolean connect(String hostname,int port,String username,String password) throws IOException{ ftpClient.connect(hostname, port); ftpClient.setControlEncoding("GBK"); if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){ if(ftpClient.login(username, password)){ return true; } } disconnect(); return false; } /** * 从FTP服务器上下载文件 * @param remote 远程文件路径 * @param local 本地文件路径 * @return 是否成功 * @throws IOException */ public DownloadStatus download(String remote,String local) throws IOException{ ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTP.BINARY_FILE_TYPE); DownloadStatus result; FTPFile[] files = ftpClient.listFiles(remote); if(files.length != 1){ System.out.println("远程文件不唯一"); return DownloadStatus.Remote_File_Noexist; } long lRemoteSize = files[0].getSize(); File f = new File(local); if(f.exists()){ long localSize = f.length(); if(localSize >= lRemoteSize){ System.out.println("本地文件大小大于远程文件大小,下载中止"); return DownloadStatus.Local_Bigger_Remote; } FileOutputStream out = new FileOutputStream(f,true); ftpClient.setRestartOffset(localSize); InputStream in = ftpClient.retrieveFileStream(remote); byte[] bytes = new byte[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); } } in.close(); out.close(); boolean isDo = ftpClient.completePendingCommand(); if(isDo){ result = DownloadStatus.Download_From_Break_Success; }else { result = DownloadStatus.Download_From_Break_Failed; } }else { OutputStream out = new FileOutputStream(f); InputStream in= ftpClient.retrieveFileStream(remote); byte[] bytes = new byte[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); } } in.close(); out.close(); boolean upNewStatus = ftpClient.completePendingCommand(); if(upNewStatus){ result = DownloadStatus.Download_New_Success; }else { result = DownloadStatus.Download_New_Failed; } } return result; } public boolean exist(String remote){ try { FTPFile[] files = ftpClient.listFiles(remote); if(files.length == 1){ return true; } return false; } catch (Exception e) { e.printStackTrace(); } return false; } /** * ftp文件删除 * @param remote * @return * @version V1.0.0 * @author * @date Oct 29, 2013 1:13:59 PM */ public boolean deleteFile(String remote){ try { if (exist(remote)) { return this.ftpClient.deleteFile(remote); } } catch (Exception e) { e.printStackTrace(); } return false; } /** * 上传文件到FTP服务器,支持断点续传 * @param local 本地文件名称,绝对路径 * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构 * @return 上传结果 * @throws IOException */ public UploadStatus upload(String local,String remote) throws IOException{ //设置PassiveMode传输 ftpClient.enterLocalPassiveMode(); //设置以二进制流的方式传输 ftpClient.setFileType(FTP.BINARY_FILE_TYPE); UploadStatus result; //对远程目录的处理 String remoteFileName = 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){ String subDirectory = remote.substring(start,end); if(!ftpClient.changeWorkingDirectory(subDirectory)){ if(ftpClient.makeDirectory(subDirectory)){ ftpClient.changeWorkingDirectory(subDirectory); }else { System.out.println("创建目录失败"); return UploadStatus.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 = new File(local); long localSize = f.length(); if(remoteSize==localSize){ return UploadStatus.File_Exits; }else if(remoteSize > localSize){ return UploadStatus.Remote_Bigger_Local; } //尝试移动文件内读取指针,实现断点续传 InputStream is = new FileInputStream(f); if(is.skip(remoteSize)==remoteSize){ ftpClient.setRestartOffset(remoteSize); if(ftpClient.storeFile(remote, is)){ return UploadStatus.Upload_From_Break_Success; } } //如果断点续传没有成功,则删除服务器上文件,重新上传 if(!ftpClient.deleteFile(remoteFileName)){ return UploadStatus.Delete_Remote_Faild; } is = new FileInputStream(f); if(ftpClient.storeFile(remote, is)){ result = UploadStatus.Upload_New_File_Success; }else{ result = UploadStatus.Upload_New_File_Failed; } is.close(); }else { InputStream is = new FileInputStream(local); if(ftpClient.storeFile(remoteFileName, is)){ result = UploadStatus.Upload_New_File_Success; }else{ result = UploadStatus.Upload_New_File_Failed; } is.close(); } return result; } /** * 断开与远程服务器的连接 * @throws IOException */ public void disconnect() throws IOException{ if(ftpClient.isConnected()){ ftpClient.disconnect(); } } /** * 创建文件夹 * @param remote * @param ftpClient * @return * @throws IOException */ public UploadStatus CreateDirecroty(String remote,FTPClient ftpClient) throws IOException{ UploadStatus status = UploadStatus.Create_Directory_Success; 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){ String subDirectory = remote.substring(start,end); if(!ftpClient.changeWorkingDirectory(subDirectory)){ if(ftpClient.makeDirectory(subDirectory)){ ftpClient.changeWorkingDirectory(subDirectory); }else { System.out.println("创建目录失败"); return UploadStatus.Create_Directory_Fail; } } start = end + 1; end = directory.indexOf("/",start); //检查所有目录是否创建完毕 if(end <= start){ break; } } } return status; } public static void main(String[] args) throws IOException, FtpConnectionException { FtpClient myFtp = new FtpClient(); try { /*boolean result = myFtp.connect("10.65.12.55", 21, "ftp_user", "111111"); System.out.println("abc------>"+result); myFtp.upload("C:/Users/Administrator/Desktop/郑州市财政局网站安全情况专报 6.doc", "/jxl/doc/郑州市财政局网站安全情况专报 6.doc"); myFtp.download("/jxl/doc/郑州市财政局网站安全情况专报 6.doc", "D:/abc.doc"); */ //UploadStatus uploadStatus = myFtp.CreateDirecroty("/chenlong/abc/", myFtp.ftpClient); //System.out.println(uploadStatus); boolean isExist = myFtp.exist("/jxl/doc/郑州市财政局网站安全情况专报 6.doc"); System.out.println("isExist------->"+isExist); myFtp.deleteFile("/jxl/doc/郑州市财政局网站安全情况专报 6.doc"); myFtp.disconnect(); } catch (IOException e) { System.out.println(e.getMessage()); } } }