FtpFileUtil


package ...;

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

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;

public class FtpFileUtil {

    private static Logger Log = Logger.getLogger(FtpFileUtil.class);
    private static String ENCODING = "GBK";
    
    private static String ftphostaddr = "...";
    private static int port = 21;
    private static String ftpname = "...";
    private static String ftppwd = "...";
    private static String ftppath = "...";
    private static String localpath = "...";
    private static String filename = "test.txt";
    
    public static void main(String[] args) {
//        // 上传文件
//        FtpUtil.uploadFile(ftphostaddr, port, ftpname, ftppwd
//                , ftppath, localpath, filename);

//        // 下载文件
//        FtpUtil.downFile(ftphostaddr, port, ftpname, ftppwd
//                , ftppath, localpath, filename);
        
//        // 删除文件
//        FtpUtil.deleteFile(ftphostaddr, port, ftpname, ftppwd
//                , ftppath, filename);
        
//        // 获取目录全部文件名称
//        for (String string : FtpUtil.getFileNames(ftphostaddr, port, ftpname, ftppwd
//                , ftppath)) {
//            System.out.println(string);
//        }
        
        
    }

    
    /**
     * 从本地上传文件到文件服务器上
     * 文件已存在追加写入
     */
    public static void uploadFile(String ftphostaddr, int port, String ftpname,
            String ftppwd, String ftppath, String localpath, String filename){
        // FTP连接
        FTPClient ftp = initFtp(ftphostaddr, port, ftpname, ftppwd);
        try {
            String fileAllName = ftppath + filename;
            Log.info("上传目录 :" + ftphostaddr+fileAllName);

            // 判断FTP目录是否存在
            boolean catalog = false;
            FTPFile[] ftpFileArr = ftp.listFiles(ftppath);
            if (ftpFileArr.length > 0) {
                catalog = true;
            }
            
            // 创建目录
            if (!catalog) {
                Log.info("目录不存在,请查看后重新尝试。");
//                boolean flag = true;
//                String newdir = new String(ftppath.getBytes(ENCODING), "ISO-8859-1");
//                flag = ftp.makeDirectory(newdir);
//                if (flag) {
//                    Log.info("make directory " + newdir + " successfully !");
//                } else {
//                    Log.info("make directory " + newdir + " failed !");
//                }
            }
            
            // 上传文件
            boolean flag = false;
            File file = new File( localpath+filename );
            InputStream input  = new FileInputStream( file );
            String remote = new String(fileAllName.getBytes(ENCODING), "ISO-8859-1");
            if (ftp.appendFile(remote, input)) {
                flag = true;
            }
            input.close();
            Log.info("push file (" + file.getCanonicalPath() + ") => " + (flag ? "SUCCESS" : "FAILED"));

            ftp.logout();
            ftp.disconnect();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            new Exception("从本地上传文件到服务器失败");
        }
    }

    
    /**
     * 从文件服务器上下载文件到本地
     * 不删除服务器文件
     * 文件追加写入
     */
    public static void downFile(String ftphostaddr, int port, String ftpname,
            String ftppwd, String ftppath, String localpath, String filename) {
        FTPClient ftp = initFtp(ftphostaddr, port, ftpname, ftppwd);
        try {
            // 4.指定要下载的目录
            ftp.changeWorkingDirectory(ftppath);// 转移到FTP服务器目录
            // 5.遍历下载的目录
            // 解决中文乱码问题,两次解码
            byte[] bytes = filename.getBytes("iso-8859-1");
            String fn = new String(bytes, "utf8");
            if (fn.equals(filename)) {
                // 6.写操作,将其写入到本地文件中
                Log.info("下载文件:  " + filename + "  开始:  "
                        + System.currentTimeMillis());
                File localFile = new File(localpath + filename);
                OutputStream is = new FileOutputStream(localFile);
                ftp.retrieveFile(filename, is);

//                // 7.判断本地文件是否正确写入,如果正确写入,将文件服务器上的文件删除
//                if (localFile.exists()) {
//                    Log.info("删除服务器上文件:" + filename);
//                    ftp.deleteFile(filename);
//                }
                
                Log.info("下载文件:  " + filename + "  结束:  "
                        + System.currentTimeMillis());
                is.close();
            }
            // 8.关闭
            ftp.logout();
            ftp.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
            new Exception("从服务器下载文件过程中发生错误");
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }

    
    /**
     * 将服务器上的文件删除
     */
    public static void deleteFile(String ftphostaddr, int port, String ftpname, String ftppwd
            , String ftppath, String filename){
        FTPClient ftp = initFtp(ftphostaddr, port, ftpname, ftppwd);
        
        Log.info("删除服务器上文件:" + filename);
        try {
            ftp.cwd(ftppath);
            ftp.deleteFile(filename);

            ftp.logout();
            ftp.disconnect();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            new Exception("将服务器上的文件删除失败");
        }
    }

    
    /**
     * 获取服务器上文件夹下全部文件的名称
     */
    public static String[] getFileNames(String ftphostaddr, int port, String ftpname, String ftppwd
            , String ftppath) {
        FTPClient ftp = initFtp(ftphostaddr, port, ftpname, ftppwd);

        try {
            ftp.cwd(ftppath);
            ftp.enterLocalPassiveMode();// 开通一个端口来传输数据
            String[] subfile = ftp.listNames();
            return subfile;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            new Exception("获取文件夹下全部文件的名称失败");
        }
        return null;
    }

    
    /**
     * 建立FTP连接
     */
    public static FTPClient initFtp(String ftphostaddr, int port,
            String ftpname, String ftppwd) {
        int reply;
        FTPClient ftp = new FTPClient();
        try {
            // 1.连接服务器
            // ftp.connect(ftphostaddr);
            ftp.connect(ftphostaddr, port);
            // 2.登录服务器 如果采用默认端口,可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(ftpname, ftppwd);
            // 3.判断登陆是否成功
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
            new Exception("服务器连接失败");
        }
        return ftp;
    }

    
    /**
     * 关闭连接
     */
    public static void closeConnect(FTPClient ftp) {
        try {
            if (ftp != null) {
                // 8.关闭
                ftp.logout();
                ftp.disconnect();
            }
            Log.info("close Connect");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
}