package cn.mr.mohurd.service.sftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;


public class FTPTool {
	private static FTPClient ftp = null; 
	private static String encoding = "";

	/**
	 * 连接ftp
	 * @param host ip地址
	 * @param port 端口
	 * @param username 用户名
	 * @param password 密码
	 * @throws Exception
	 * ftp.enterLocalPassiveMode();增加改行的用意:在项目中使用commons-net-3.0.1.jar实现FTP文件的下载,在windows xp上运行正常,
	 * 但是放到linux上,却出现问题,程序运行到FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态。
	 * 解决方案为:在调用这两个方法之前,调用FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,
	 * ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,
	 * 但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。
	 */
	public static void getConnect(String host, int port, String username, String password) throws Exception {
		try {
			ftp = new FTPClient(); 
	    	ftp.connect(host, port);//连接FTP服务器    
	    	ftp.login(username, password);//登录    
	    	int reply = ftp.getReplyCode();   
	        if (!FTPReply.isPositiveCompletion(reply)) { 
	        	disConn(); 
	        	throw new IOException();
	        } 
	        ftp.enterLocalPassiveMode();
	        encoding = System.getProperty("file.encoding");
			ftp.setControlEncoding(encoding);
	        ftp.setFileType(FTPClient.BINARY_FILE_TYPE); //文件二进制编码
		} catch (Exception e){
			System.out.print(e.getMessage()+e);
			throw new Exception("连接ftp服务器失败,请检查主机[" + host + "],端口[" + port   
	                + "],用户名[" + username + "],密码[" + password   
	                + "]是否正确,以上信息正确的情况下请检查网络连接是否正常或者请求被防火墙拒绝."); 
		}
	}

	/**
	 * 断开连接
	 * 参看父类中的注释 @see cn.mr.mohurd.service.sftp.FileTransferService#disConn()
	 */
	public static void disConn() throws Exception{
		try {
	    	if (ftp.isConnected()) {
	        	ftp.logout();
	            ftp.disconnect();   
	        }
		} catch (Exception e) {   
			throw new Exception("断开ftp连接失败"); 
	    }
	}

	/**
	 * 上传文件
	 * @param directory 目标路径
	 * @param uploadFile被上传的文件目录包括文件名
	 * @throws Exception
	 */
	public static void upload(String directory,String uploadFile) throws Exception {
		try {
			//如果目录不存在,则创建目录
		    if (directory != null && !"".equals(directory.trim())) {
		        String[] pathes = directory.split("/");
		        for (String onepath : pathes) {
		            if (onepath == null || "".equals(onepath.trim())) {
		                continue;
		            }
		            onepath=new String(onepath);                    
		            if (!ftp.changeWorkingDirectory(onepath)) {
		                ftp.makeDirectory(onepath);
		                ftp.changeWorkingDirectory(onepath);//跳转至目标目录,若目录不存在则会创建不存在的目录
		            }
		        }
		    }
		    File file = new File(uploadFile);
		    FileInputStream input = new FileInputStream(file);
		    ftp.storeFile(file.getName(), input); 
	        input.close();   
	    } catch (Exception e) {
	        throw new Exception("文件上传失败!"+e.getMessage()); 
	    } finally {
	    	disConn();
	    }
	}

	/**
	 * 下载文件
	 * @param directory 
	 * @param downloadFile 下载文件的文件名
	 * @param saveFile 下载后文件存放的路径
	 * @throws Exception
	 */
	public static void download(String directory, String downloadFile,String saveFile) throws Exception {
		try {
	    	ftp.changeWorkingDirectory(directory);//转移到FTP服务器目录  
	        FTPFile[] fs = ftp.listFiles();  
	        boolean hasFile = false;
	        for(FTPFile ff:fs){  
	            if(ff.getName().equals(downloadFile)){ 
	                hasFile = true;
	                File localFile = new File(saveFile);
	                if (!localFile.exists()) {
	                	localFile.mkdirs();
	                }
	                OutputStream is = new FileOutputStream(localFile+"/"+downloadFile);   
	                ftp.retrieveFile(ff.getName(), is);  
	                is.close();  
	            }  
	        }
	        if (!hasFile){
	            throw new Exception("没有在指定目录"+directory+"找到需要下载的文件"+downloadFile); 
	        }
		} catch (Exception e){
		    throw new Exception(e); 
		} finally {
	    	disConn();
	    }
	}

	/**
	 * 删除文件
	 * @param directory 需要删除文件的路径
	 * @param deleteFile 文件名
	 * @throws Exception
	 */
	public static void delete(String directory, String deleteFile) throws Exception {
		try {
			if (!ftp.deleteFile(directory+"/"+deleteFile)){
				throw new Exception("删除文件失败,原因为"+ftp.getReplyString()); 
			}		
	    } catch (Exception e) {
	    	throw new Exception(e.getMessage(),e); 
	    } finally {
	    	disConn();
	    }
	}
	
	public static void main(String[] args) {
	    try {
            getConnect("192.168.1.243", 21, "mohurd", "mohurd!@#$");
            upload("/LocateList_ICT2ESOP/1024/","C:/Documents and Settings/Administrator/My Documents/NewMobile_ESOP2ICT_201412_23.txt");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
	}
}
<pre name="code" class="java">package cn.mr.mohurd.service.sftp;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
import java.util.Vector;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

/**
 * sftp相关工具类
 * 2013-11-7 下午12:41:18
 */
public class SFTPTool {
    private static Session session;   
    private static Channel channel;   
    private static ChannelSftp sftp;// sftp操作类    
    
    /**
     * 连接sftp
     * 构造函数
     * @param host
     * @param port
     * @param username
     * @param password
     * @throws Exception
     */
    public SFTPTool(String host, int port, String username, String password) throws Exception {   
        getConnect(host, port, username, password);
    }   

    
    /**
     * 连接sftp服务器
     * @param host 主机
     * @param port 端口
     * @param uname 用户名
     * @param username 密码
     * @return
     * @throws Exception 
     */
    private static ChannelSftp getConnect(String host, int port, String username, String password) throws Exception {
        JSch jsch = new JSch();   
        session = jsch.getSession(username, host, port);   
        session.setPassword(password);   
        Properties config = new Properties();   
        config.put("StrictHostKeyChecking", "no"); // 不验证 HostKey    
        session.setConfig(config);   
        try {
            session.connect();   
        } catch (Exception e) {
            if (session.isConnected())   
                session.disconnect();   
            throw new Exception("连接服务器失败,请检查主机[" + host + "],端口[" + port   
                    + "],用户名[" + username + "],端口[" + port   
                    + "]是否正确,以上信息正确的情况下请检查网络连接是否正常或者请求被防火墙拒绝.");   
        }
        channel = session.openChannel("sftp");   
        try {
            channel.connect();   
        } catch (Exception e) {   
            if (channel.isConnected())   
                channel.disconnect();   
            throw new Exception("连接服务器失败,请检查主机[" + host + "],端口[" + port   
                    + "],用户名[" + username + "],密码[" + password   
                    + "]是否正确,以上信息正确的情况下请检查网络连接是否正常或者请求被防火墙拒绝.");   
        }
        sftp = (ChannelSftp) channel;   
        
        return sftp;
    }
    
    /**
     * 断开连接
     */
    private static void disConn(){
        if(null != sftp){
            sftp.disconnect();
            sftp.exit();
            sftp = null;
        }
        if(null != channel){
            channel.disconnect();
            channel = null;
        }
        if(null != session){
            session.disconnect();
            session = null;
        }
    }

    /**
     * 上传文件,同时断开连接
     * @param directory  上传指定的路径
     * @param uploadFile 需要上传的文件的路径级文件名
     * @throws Exception
     */
    public void upload(String directory,String uploadFile) throws Exception {
        try {
            if (!directory.equals("") && directory.trim() != "") {  
                try{
                    sftp.cd(directory);  
                }catch(SftpException sException){
                    if(sftp.SSH_FX_NO_SUCH_FILE == sException.id){ //指定上传路径不存在
                        sftp.mkdir(directory);
                        sftp.cd(directory);  
                    }
                }
            }
            File file = new File(uploadFile);
            sftp.put(new FileInputStream(file), file.getName());
        } catch (Exception e) {
            throw new Exception(e.getMessage(),e); 
        } finally{
            disConn();
        }
    }

    /**
     * 下载文件,同时断开连接
     * @param directory 下载目录
     * @param downloadFile 下载的文件名
     * @param saveFile 存在本地的全路径
     * @throws Exception 
     */
    public void download(String directory, String downloadFile,String saveFile) throws Exception {
        try {
            sftp.cd(directory); 
            File file = new File(saveFile);
            boolean bFile;
            bFile = false;
            bFile = file.exists();
            if (!bFile) {
                bFile = file.mkdirs();
            }
            sftp.get(downloadFile, new FileOutputStream(new File(saveFile,downloadFile)));
        } catch (Exception e) {
            throw new Exception(e.getMessage(),e); 
        } finally{
            disConn();
        }
    }

    /**
     * 删除文件,同时断开连接
     * @param directory 要删除文件所在目录
     * @param deleteFile  要删除的文件名
     * @param sftp
     * @throws Exception 
     */
    public void delete(String directory, String deleteFile) throws Exception {
        try {
            sftp.cd(directory);  
            sftp.rm(deleteFile);
        } catch (Exception e) {
            throw new Exception(e.getMessage(),e); 
        } finally{
            disConn();
        }
    }

    /**
     * 列出目录下的文件
     * @param directory 要列出的文件
     * @return
     * @throws SftpException
     */
    public Vector listFiles(String directory)throws SftpException {
        Vector vec = sftp.ls(directory);
        disConn();
        return vec;
    }
    
    /**
     * 用于查询某个远程目录下的文件名称
     * @param directory 远程目录
     * @param valiStr
     * @param map
     * @return
     * @throws SftpException
     */
    public Vector<String> listFileNames(String directory, String valiStr)
            throws SftpException {
        Vector<String> ret = new Vector<String>();
        System.out.println("------");
        for (Object obj : sftp.ls(directory)) {
            String curStr = obj.toString();
            curStr = curStr.substring(curStr.lastIndexOf(" ")+1);
            
            if(curStr.contains(valiStr)){
                ret.add(curStr);
            }
        }
        disConn();
        return ret;
    }
}