用apache FTP client实现FTP客户端--支持断点续传和中文文件 .

 

可以参考:http://blog.csdn.net/xiaozhang0731/article/details/5669151

 

 

主要使用apache中的net包来实现。网址http://commons.apache.org/net/。具体包的下载和API文档请看官网。

    断点上传就是在上传的过程中设置传输的起始位置。并设置二进制传输。

Java代码 复制代码  收藏代码
  1. package apache.net.test;   
  2.   
  3. import java.io.File;   
  4. import java.io.FileInputStream;   
  5. import java.io.FileOutputStream;   
  6. import java.io.IOException;   
  7. import java.io.InputStream;   
  8. import java.io.OutputStream;   
  9. import java.io.PrintWriter;   
  10. import org.apache.commons.net.PrintCommandListener;   
  11. import org.apache.commons.net.ftp.FTP;   
  12. import org.apache.commons.net.ftp.FTPClient;   
  13. import org.apache.commons.net.ftp.FTPFile;   
  14. import org.apache.commons.net.ftp.FTPReply;   
  15.   
  16. public class ContinueFTP {   
  17.     private FTPClient ftpClient = new FTPClient();   
  18.        
  19.     public ContinueFTP(){   
  20.         //设置将过程中使用到的命令输出到控制台   
  21.         this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));   
  22.     }   
  23.        
  24.     /**  
  25.      * 连接到FTP服务器  
  26.      * @param hostname 主机名  
  27.      * @param port 端口  
  28.      * @param username 用户名  
  29.      * @param password 密码  
  30.      * @return 是否连接成功  
  31.      * @throws IOException  
  32.      */  
  33.     public boolean connect(String hostname,int port,String username,String password) throws IOException{   
  34.         ftpClient.connect(hostname, port);   
  35.         if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){   
  36.             if(ftpClient.login(username, password)){   
  37.                 return true;   
  38.             }   
  39.         }   
  40.         disconnect();   
  41.         return false;   
  42.     }   
  43.        
  44.     /**  
  45.      * 从FTP服务器上下载文件  
  46.      * @param remote 远程文件路径  
  47.      * @param local 本地文件路径  
  48.      * @return 是否成功  
  49.      * @throws IOException  
  50.      */  
  51.     public boolean download(String remote,String local) throws IOException{   
  52.         ftpClient.enterLocalPassiveMode();   
  53.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);   
  54.         boolean result;   
  55.         File f = new File(local);   
  56.         FTPFile[] files = ftpClient.listFiles(remote);   
  57.         if(files.length != 1){   
  58.             System.out.println("远程文件不唯一");   
  59.             return false;   
  60.         }   
  61.         long lRemoteSize = files[0].getSize();   
  62.         if(f.exists()){   
  63.             OutputStream out = new FileOutputStream(f,true);   
  64.             System.out.println("本地文件大小为:"+f.length());   
  65.             if(f.length() >= lRemoteSize){   
  66.                 System.out.println("本地文件大小大于远程文件大小,下载中止");   
  67.                 return false;   
  68.             }   
  69.             ftpClient.setRestartOffset(f.length());   
  70.             result = ftpClient.retrieveFile(remote, out);   
  71.             out.close();   
  72.         }else {   
  73.             OutputStream out = new FileOutputStream(f);   
  74.             result = ftpClient.retrieveFile(remote, out);   
  75.             out.close();   
  76.         }   
  77.         return result;   
  78.     }   
  79.        
  80.     /**  
  81.      * 上传文件到FTP服务器,支持断点续传  
  82.      * @param local 本地文件名称,绝对路径  
  83.      * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext 按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构  
  84.      * @return 上传结果  
  85.      * @throws IOException  
  86.      */  
  87.     public UploadStatus upload(String local,String remote) throws IOException{   
  88.         //设置PassiveMode传输   
  89.         ftpClient.enterLocalPassiveMode();   
  90.         //设置以二进制流的方式传输   
  91.         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);   
  92.         UploadStatus result;   
  93.         //对远程目录的处理   
  94.         String remoteFileName = remote;   
  95.         if(remote.contains("/")){   
  96.             remoteFileName = remote.substring(remote.lastIndexOf("/")+1);   
  97.             String directory = remote.substring(0,remote.lastIndexOf("/")+1);   
  98.             if(!directory.equalsIgnoreCase("/")&&!ftpClient.changeWorkingDirectory(directory)){   
  99.                 //如果远程目录不存在,则递归创建远程服务器目录   
  100.                 int start=0;   
  101.                 int end = 0;   
  102.                 if(directory.startsWith("/")){   
  103.                     start = 1;   
  104.                 }else{   
  105.                     start = 0;   
  106.                 }   
  107.                 end = directory.indexOf("/",start);   
  108.                 while(true){   
  109.                     String subDirectory = remote.substring(start,end);   
  110.                     if(!ftpClient.changeWorkingDirectory(subDirectory)){   
  111.                         if(ftpClient.makeDirectory(subDirectory)){   
  112.                             ftpClient.changeWorkingDirectory(subDirectory);   
  113.                         }else {   
  114.                             System.out.println("创建目录失败");   
  115.                             return UploadStatus.Create_Directory_Fail;   
  116.                         }   
  117.                     }   
  118.                        
  119.                     start = end + 1;   
  120.                     end = directory.indexOf("/",start);   
  121.                        
  122.                     //检查所有目录是否创建完毕   
  123.                     if(end <= start){   
  124.                         break;   
  125.                     }   
  126.                 }   
  127.             }   
  128.         }   
  129.            
  130.         //检查远程是否存在文件   
  131.         FTPFile[] files = ftpClient.listFiles(remoteFileName);   
  132.         if(files.length == 1){   
  133.             long remoteSize = files[0].getSize();   
  134.             File f = new File(local);   
  135.             long localSize = f.length();   
  136.             if(remoteSize==localSize){   
  137.                 return UploadStatus.File_Exits;   
  138.             }else if(remoteSize > localSize){   
  139.                 return UploadStatus.Remote_Bigger_Local;   
  140.             }   
  141.                
  142.             //尝试移动文件内读取指针,实现断点续传   
  143.             InputStream is = new FileInputStream(f);   
  144.             if(is.skip(remoteSize)==remoteSize){   
  145.                 ftpClient.setRestartOffset(remoteSize);   
  146.                 if(ftpClient.storeFile(remote, is)){   
  147.                     return UploadStatus.Upload_From_Break_Success;   
  148.                 }   
  149.             }   
  150.                
  151.             //如果断点续传没有成功,则删除服务器上文件,重新上传   
  152.             if(!ftpClient.deleteFile(remoteFileName)){   
  153.                 return UploadStatus.Delete_Remote_Faild;   
  154.             }   
  155.             is = new FileInputStream(f);   
  156.             if(ftpClient.storeFile(remote, is)){       
  157.                 result = UploadStatus.Upload_New_File_Success;   
  158.             }else{   
  159.                 result = UploadStatus.Upload_New_File_Failed;   
  160.             }   
  161.             is.close();   
  162.         }else {   
  163.             InputStream is = new FileInputStream(local);   
  164.             if(ftpClient.storeFile(remoteFileName, is)){   
  165.                 result = UploadStatus.Upload_New_File_Success;   
  166.             }else{   
  167.                 result = UploadStatus.Upload_New_File_Failed;   
  168.             }   
  169.             is.close();   
  170.         }   
  171.         return result;   
  172.     }   
  173.     /**  
  174.      * 断开与远程服务器的连接  
  175.      * @throws IOException  
  176.      */  
  177.     public void disconnect() throws IOException{   
  178.         if(ftpClient.isConnected()){   
  179.             ftpClient.disconnect();   
  180.         }   
  181.     }   
  182.        
  183.     public static void main(String[] args) {   
  184.         ContinueFTP myFtp = new ContinueFTP();   
  185.         try {   
  186.             myFtp.connect("192.168.21.171"21"test""test");   
  187.             System.out.println(myFtp.upload("E:\\VP6.flv""/MIS/video/VP6.flv"));   
  188.             myFtp.disconnect();   
  189.         } catch (IOException e) {   
  190.             System.out.println("连接FTP出错:"+e.getMessage());   
  191.         }   
  192.     }   
  193. }  
package apache.net.test;

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 = new FTPClient();
	
	public ContinueFTP(){
		//设置将过程中使用到的命令输出到控制台
		this.ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
	}
	
	/**
	 * 连接到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);
		if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
			if(ftpClient.login(username, password)){
				return true;
			}
		}
		disconnect();
		return false;
	}
	
	/**
	 * 从FTP服务器上下载文件
	 * @param remote 远程文件路径
	 * @param local 本地文件路径
	 * @return 是否成功
	 * @throws IOException
	 */
	public boolean download(String remote,String local) throws IOException{
		ftpClient.enterLocalPassiveMode();
		ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
		boolean result;
		File f = new File(local);
		FTPFile[] files = ftpClient.listFiles(remote);
		if(files.length != 1){
			System.out.println("远程文件不唯一");
			return false;
		}
		long lRemoteSize = files[0].getSize();
		if(f.exists()){
			OutputStream out = new FileOutputStream(f,true);
			System.out.println("本地文件大小为:"+f.length());
			if(f.length() >= lRemoteSize){
				System.out.println("本地文件大小大于远程文件大小,下载中止");
				return false;
			}
			ftpClient.setRestartOffset(f.length());
			result = ftpClient.retrieveFile(remote, out);
			out.close();
		}else {
			OutputStream out = new FileOutputStream(f);
			result = ftpClient.retrieveFile(remote, out);
			out.close();
		}
		return result;
	}
	
	/**
	 * 上传文件到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();
		}
	}
	
	public static void main(String[] args) {
		ContinueFTP myFtp = new ContinueFTP();
		try {
			myFtp.connect("192.168.21.171", 21, "test", "test");
			System.out.println(myFtp.upload("E:\\VP6.flv", "/MIS/video/VP6.flv"));
			myFtp.disconnect();
		} catch (IOException e) {
			System.out.println("连接FTP出错:"+e.getMessage());
		}
	}
}

 其中部分代码,如服务器连接,断开,打印命令到控制台等来自于互联网

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值