ftp工具类

package com.xxx.zjdlbb.service.zjdlbb;

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.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

/**
 ******************************************************************************* 
 * 文件名称:FTPService.java 系统名称: 类 概 述: FTP文件上传下载 创建日期:2015年4月3日 下午5:17:52 版 本: V1.0.0
 ******************************************************************************* 
 */
public class FTPService {
    private Logger log = Logger.getLogger(getClass());
    protected static String FTP_CONTROL_ENCODING = "ISO-8859-1";
    protected static String FTP_CHARSET_NAME;
    protected static String FTP_SYSTEM_TYPE;
    protected static String LOCAL_FILE_ENCODING = System.getProperty("file.encoding");
    protected static String LOCAL_SYSTEM_TYPE = System.getProperty("os.name");
    public static String FTP_CONTROL_ENCODING_LOCAL = "GBK";

    /**
     * @Description 概要说明:上传文件到FTP服务器
     * 
     * @date 2015年4月6日 下午4:12:51
     * @update xxx(yyyy-MM-dd)
     * @param ip
     *            FTP服务器IP地址
     * @param port
     *            端口
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @param remoteDir
     *            FTP保存文件的目录
     * @param localFile
     *            本地需要上传的文件
     * @return boolean
     */
    public boolean upload(String ip, int port, String username, String pwd, String remoteDir, String localFile) {
        File in = new File(localFile);
        return upload(ip, port, username, pwd, remoteDir, in);
    }

    /**
     * @Description 概要说明:上传文件到FTP服务器
     * 
     * @date 2015年4月6日 下午4:12:51
     * @update xxx(yyyy-MM-dd)
     * @param ip
     *            FTP服务器IP地址
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @param remoteDir
     *            FTP保存文件的目录
     * @param localFile
     *            本地需要上传的文件
     * @return boolean
     */
    public boolean upload(String ip, String username, String pwd, String remoteDir, String localFile) {
        File in = new File(localFile);
        return upload(ip, username, pwd, remoteDir, in);
    }

    /**
     * @Description 概要说明:上传文件到FTP服务器
     * 
     * @date 2015年4月6日 下午4:12:51
     * @update xxx(yyyy-MM-dd)
     * @param ip
     *            FTP服务器IP地址
     * @param port
     *            端口
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @param remoteDir
     *            FTP保存文件的目录
     * @param in
     *            本地需要上传的文件
     * @return boolean
     */
    public boolean upload(String ip, int port, String username, String pwd, String remoteDir, File in) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            // 建立连接、登录
            success = login(ftp, ip, username, pwd);
            if (!success) {
                return success;
            }
            uploadFile(ftp, remoteDir, in);
            // 退出登录
            ftp.logout();
            success = true;
        } catch (IOException e) {
            log.error("", e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * @Description 概要说明:上传文件到FTP服务器
     * 
     * @date 2015年4月6日 下午4:12:51
     * @update xxx(yyyy-MM-dd)
     * @param ip
     *            FTP服务器IP地址
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @param remoteDir
     *            FTP保存文件的目录
     * @param in
     *            本地需要上传的文件
     * @return boolean
     */
    public boolean upload(String ip, String username, String pwd, String remoteDir, File in) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            // 建立连接、登录
            success = login(ftp, ip, username, pwd);
            if (!success) {
                return success;
            }
            uploadFile(ftp, remoteDir, in);
            // 退出登录
            ftp.logout();
            success = true;
        } catch (IOException e) {
            log.error("", e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * @Description 概要说明:本地文件上传到FTP指定目录
     * 
     * @date 2015年4月6日 下午4:16:10
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     *            FTP对象
     * @param remoteDir
     *            FTP目录
     * @param in
     *            本地文件
     * @return void
     * @throws IOException
     */
    public void uploadFile(FTPClient ftp, String remoteDir, File in) throws IOException {
        String fileName = in.getName();
        try {
            if (!in.exists()) {
                throw new IOException("文件[" + fileName + "]不存在!");
            } else {
                if (in.isDirectory()) {
                    remoteDir = remoteDir + "/" + fileName;
                    ftp.makeDirectory(local2Remote_encoding(remoteDir));
                    File[] files = in.listFiles();
                    for (File tmp : files) {
                        uploadFile(ftp, remoteDir, tmp);
                    }
                } else {
                    uploadFile(ftp, remoteDir, fileName, in);
                }
            }
            log.info("[" + fileName + "/" + in.length() / 1024 + "KB]上传成功!");
        } catch (IOException e) {
            log.info("[" + fileName + "]上传失败!");
            throw e;
        }
    }

    /**
     * @Description 概要说明:文件上传
     * 
     * @date 2015年4月6日 下午4:54:21
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     * @param remoteDir
     * @param fileName
     * @param in
     * @throws IOException
     *             void
     */
    public void uploadFile(FTPClient ftp, String remoteDir, String fileName, File in) throws IOException {
        remoteDir = local2Remote_encoding(remoteDir + "/");
        ftp.changeWorkingDirectory(remoteDir);
        fileName = local2Remote_encoding(fileName);
        InputStream input = null;
        try {
            log.debug("localFile:" + in.getAbsolutePath());
            input = new FileInputStream(in);
            boolean isSucc = ftp.storeFile(fileName, input);
            if (!isSucc) {
                throw new IOException("文件[" + fileName + "/" + (in.getTotalSpace() / 1024) + "Kb]上传失败!");
            }
        } catch (IOException e) {
            throw e;
        } finally {
            input.close();
        }
    }

    /**
     * @Description 概要说明:从FTP上下载文件
     * 
     * @date 2015年4月3日 下午10:53:43
     * @update xxx(yyyy-MM-dd)
     * @param ip
     *            FTP服务器IP地址
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @param remoteDir
     *            需要下载的目标目录
     * @param localDir
     *            本地保存目录
     * @return boolean
     */
    public List<File> download(String ip, String username, String pwd, String remoteDir, String localDir) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        List<File> list = null;
        try {
            // 建立连接、登录
            success = login(ftp, ip, username, pwd);
            if (!success) {
                return list;
            }
            list = downloadFile(ftp, remoteDir, localDir);
            // 退出登录
            ftp.logout();
        } catch (IOException e) {
            log.error("", e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return list;
    }

    /**
     * @Description 概要说明:从FTP服务器上下载文件
     * 
     * @date 2015年4月3日 下午10:46:05
     * @update xxx(yyyy-MM-dd)
     * @param ip
     *            FTP服务器IP地址
     * @param port
     *            端口号
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @param remoteDir
     *            需要下载的目标目录
     * @param localDir
     *            本地保存目录
     * @return boolean
     */
    public List<File> download(String ip, int port, String username, String pwd, String remoteDir, String localDir) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        List<File> list = null;
        try {
            success = login(ftp, ip, port, username, pwd);
            if (!success) {
                return list;
            }
            list = downloadFile(ftp, remoteDir, localDir);
            ftp.logout();
        } catch (IOException e) {
            log.error("", e);
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return list;
    }

    /**
     * @Description 概要说明:过滤本目录以及父级目录
     * 
     * @date 2015年4月4日 上午12:00:15
     * @update xxx(yyyy-MM-dd)
     * @param fs
     * @return List<FTPFile>
     */
    protected List<FTPFile> filterSelf(FTPClient ftp, FTPFile[] fs) throws UnsupportedEncodingException {
        List<FTPFile> list = new ArrayList<FTPFile>();
        for (FTPFile tmp : fs) {
            String tmpName = tmp.getName();
            Pattern p1 = Pattern.compile("^\\.$");
            Matcher m1 = p1.matcher(tmpName);
            Pattern p2 = Pattern.compile("^\\.\\.$");
            Matcher m2 = p2.matcher(tmpName);
            boolean self1 = m1.find();
            boolean self2 = m2.find();
            if (!self1 && !self2) {
                list.add(tmp);
            }
        }
        return list;
    }

    /**
     * @Description 概要说明:文件过滤逻辑,重写自定义逻辑
     * 
     * @date 2015年4月3日 下午10:38:03
     * @update xxx(yyyy-MM-dd)
     * @param fs
     * @return List<FTPFile>
     */
    protected List<FTPFile> filter(FTPClient ftp, List<FTPFile> fs, Object... params) {
        List<FTPFile> files = new ArrayList<FTPFile>();
        List<FTPFile> dirs = new ArrayList<FTPFile>();
        for (FTPFile tmp : fs) {
            if (tmp.isDirectory()) {
                dirs.add(tmp);
            } else {
                files.add(tmp);
            }
        }
        files.addAll(dirs);
        return files;
    }

    /**
     * @Description 概要说明:下载文件到本地
     * 
     * @date 2015年4月3日 下午5:22:18
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     *            ftp对象
     * @param files
     *            远程主机文件集合
     * @param localDir
     *            需要下载到本地目录
     * @throws IOException
     *             void
     */
    public List<File> downloadFile(FTPClient ftp, String remoteDir, String localDir) throws IOException {
        String tmpRemote = local2Remote_encoding(remoteDir);
        ftp.changeWorkingDirectory("~");
        ftp.changeWorkingDirectory(tmpRemote);
        FTPFile[] fs = ftp.listFiles();
        List<File> list = new ArrayList<File>();
        // 过滤文件
        List<FTPFile> files = filter(ftp, filterSelf(ftp, fs));
        // 递归下载
        for (FTPFile file : files) {
            try {
                String tmpName = file.getName();
                if (file.isDirectory()) {
                    String remoteTmpDir = remoteDir + "/" + tmpName + "/";
                    String localTmpDir = localDir + "/" + tmpName + "/";
                    File localTmpFile = new File(localTmpDir);
                    if (localTmpFile.exists()) {
                        if (!localTmpFile.isDirectory()) {
                            throw new IOException("文件[" + localTmpFile.getName() + "]不是目录!");
                        }
                    } else {
                        localTmpFile.mkdirs();
                    }
                    list.addAll(downloadFile(ftp, remoteTmpDir, localTmpDir));
                } else {
                    File f = downloadFile(ftp, file, remoteDir, localDir);
                    if (f != null) {
                        list.add(f);
                        log.info("文件[" + file.getName() + "/" + file.getSize() / (1024) + "KB]下载成功!");
                    }
                }
            } catch (IOException e) {
                log.info("文件[" + file.getName() + "]下载失败!");
                throw e;
            }
        }

        return list;
    }

    /**
     * @Description 概要说明:下载文件到本地
     * 
     * @date 2015年4月3日 下午5:21:30
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     *            ftp对象
     * @param file
     *            远程主机文件
     * @param localDir
     *            需要下载到本地目录
     * @throws IOException
     *             void
     */
    public File downloadFile(FTPClient ftp, FTPFile file, String remoteDir, String localDir) throws IOException {
        String tmpName = file.getName();
        ftp.changeWorkingDirectory("~");
        remoteDir = local2Remote_encoding(remoteDir);
        ftp.changeWorkingDirectory(remoteDir);
        File localFile = new File(localDir + File.separator + tmpName);
        tmpName = local2Remote_encoding(tmpName);
        OutputStream os = null;
        boolean isSucc = false;
        try {
            log.debug("localFile:" + localFile.getAbsoluteFile());
            os = new FileOutputStream(localFile);
            isSucc = ftp.retrieveFile(tmpName, os);
            if (isSucc) {
                return localFile;
            }/*
             * else{ try { InputStream in = ftp.retrieveFileStream("/"+remoteDir+"/"+tmpName); int len = -1; byte[] readB = new byte[1024]; while ((len = in.read(readB)) != -1) { os.write(readB, 0, len); os.flush(); } isSucc = true; return localFile; } catch (IOException e) { throw e; } }
             */
            return null;
        } catch (IOException e) {
            throw e;
        } finally {
            os.close();
            if (!isSucc && localFile.exists()) {
                log.warn("文件[" + tmpName + "/" + (file.getSize() / 1024) + "Kb]下载失败!");
                localFile.delete();
            }
        }
    }

    /**
     * @Description 概要说明:登录FTP
     * 
     * @date 2015年4月3日 下午5:22:44
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     *            FTP对象
     * @param ip
     *            FTP主机IP地址
     * @param port
     *            端口
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @return
     * @throws SocketException
     * @throws IOException
     *             boolean
     */
    protected boolean login(FTPClient ftp, String ip, int port, String username, String pwd) throws SocketException, IOException {
        ftp.connect(ip, port);
        ftp.login(username, pwd);
        int reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftp.disconnect();
            return false;
        }
        log.info("FTP Server IP:" + ip);
        log.info("FTP Server User:" + username + " login success.");
        reply = ftp.sendCommand("OPTS UTF8", "ON");
        if (FTPReply.isPositiveCompletion(reply)) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
            FTP_CONTROL_ENCODING_LOCAL = "UTF-8";
        }

        FTP_SYSTEM_TYPE = ftp.getSystemType();
        FTP_CHARSET_NAME = ftp.getCharsetName();
        FTP_CONTROL_ENCODING = ftp.getControlEncoding();

        // 解决文件名乱码问题
        ftp.setControlEncoding(FTP_CONTROL_ENCODING_LOCAL);
        ftp.enterLocalPassiveMode();// 设置被动模式
        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式

        return true;
    }

    /**
     * @Description 概要说明:登录FTP
     * 
     * @date 2015年4月3日 下午5:23:25
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     *            FTP对象
     * @param ip
     *            FTP主机IP地址
     * @param username
     *            用户名
     * @param pwd
     *            密码
     * @return
     * @throws SocketException
     * @throws IOException
     *             boolean
     */
    protected boolean login(FTPClient ftp, String ip, String username, String pwd) throws SocketException, IOException {
        ftp.connect(ip);
        ftp.login(username, pwd);
        int reply = ftp.getReplyCode();
        if (!FTPReply.isPositiveCompletion(reply)) {
            ftp.disconnect();
            return false;
        }
        log.info("FTP Server IP:" + ip);
        log.info("FTP Server User:" + username + " login success.");
        reply = ftp.sendCommand("OPTS UTF8", "ON");
        if (FTPReply.isPositiveCompletion(reply)) {// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
            FTP_CONTROL_ENCODING_LOCAL = "UTF-8";
        }

        FTP_SYSTEM_TYPE = ftp.getSystemType();
        FTP_CHARSET_NAME = ftp.getCharsetName();
        FTP_CONTROL_ENCODING = ftp.getControlEncoding();

        // 解决文件名乱码问题
        ftp.setControlEncoding(FTP_CONTROL_ENCODING_LOCAL);
        ftp.enterLocalPassiveMode();// 设置被动模式
        ftp.setFileType(FTPClient.BINARY_FILE_TYPE);// 设置传输的模式

        return true;
    }

    public String remote2Local_encoding(String remote) {
        String result = null;
        try {
            result = new String(remote.getBytes(FTP_CONTROL_ENCODING), FTP_CONTROL_ENCODING_LOCAL);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }
        return result;
    }

    public String local2Remote_encoding(String local) {
        String result = null;
        try {
            result = new String(local.getBytes(FTP_CONTROL_ENCODING_LOCAL), FTP_CONTROL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }
        return result;
    }

    public String sys2Local_encoding(String sys) {
        String result = null;
        try {
            result = new String(sys.getBytes(), FTP_CONTROL_ENCODING_LOCAL);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }
        return result;
    }

    public String sys2Remote_encoding(String sys) {
        String result = null;
        try {
            result = new String(sys.getBytes(), FTP_CONTROL_ENCODING);
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
        }
        return result;
    }

    /**
     * @Description 概要说明:是否最新文件
     * 
     * @date 2016年1月20日 下午3:49:47
     * @update xxx(yyyy-MM-dd)
     * @param ftp
     * @param file
     * @param remoteDir
     * @return
     * @throws IOException
     *             boolean
     */
    public boolean isLast(FTPClient ftp, FTPFile file, String remoteDir) throws IOException {
        String tmpRemote = local2Remote_encoding(remoteDir);
        ftp.changeWorkingDirectory("~");
        ftp.changeWorkingDirectory(tmpRemote);
        FTPFile[] ftpFiles = ftp.listFiles();
        List<FTPFile> files = filter(ftp, filterSelf(ftp, ftpFiles));
        long lastTime = 0;
        FTPFile tmpFile = null;
        for (FTPFile ftpFile : files) {
            long tmpLastTime = ftpFile.getTimestamp().getTimeInMillis();
            if (tmpLastTime > lastTime) {
                lastTime = tmpLastTime;
                tmpFile = ftpFile;
            }
        }

        return tmpFile == null ? false : file.getName().equals(tmpFile.getName());
    }

    /**
     * @Description 概要说明:匹配结束字符文件
     * @date 2016年1月20日 下午3:49:47
     * @update xxx(yyyy-MM-dd)
     * @param file
     *            FTP文件对象
     * @param end
     *            结束字符
     * @return
     * @throws IOException
     *             boolean
     */
    public boolean endWith(FTPFile file, String end) throws IOException {
        if (null == end) {
            end = "";
        }
        return file.getName().endsWith(end);
    }

    public boolean isLastAndEndWith(FTPClient ftp, FTPFile file, String remoteDir, String end) throws IOException {
        if (file.getName().endsWith(end)) {
            String tmpRemote = local2Remote_encoding(remoteDir);
            ftp.changeWorkingDirectory("~");
            ftp.changeWorkingDirectory(tmpRemote);
            FTPFile[] ftpFiles = ftp.listFiles();
            List<FTPFile> files = filter(ftp, filterSelf(ftp, ftpFiles));
            long lastTime = 0;
            FTPFile tmpFile = null;
            for (FTPFile ftpFile : files) {
                long tmpLastTime = ftpFile.getTimestamp().getTimeInMillis();
                if (ftpFile.getName().endsWith(end) && tmpLastTime > lastTime) {
                    lastTime = tmpLastTime;
                    tmpFile = ftpFile;
                }
            }

            return tmpFile == null ? false : file.getName().equals(tmpFile.getName());
        }

        return false;
    }

    public static void main(String args[]) {
        FTPService ftp = new FTPService();
        String ip = "127.0.0.1";
        int port = 1111;
        String username = "crd";
        String pwd = "crd";
        String remoteDir = "";
        String localDir = "C:/Users/Administrator/Desktop/test";
        ftp.download(ip, port, username, pwd, remoteDir, localDir);
        System.out.println(122);
    }

}

 

posted @ 2018-12-25 19:04  爱跳舞的程序员  阅读(263)  评论(0编辑  收藏  举报