Ftp上传下载

来源:互联网 发布:那些年很红的网络歌曲 编辑:程序博客网 时间:2024/05/21 08:51
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 org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ncs.common.FtpStatusEnum;

/**
 * 利用 commons-net链接ftp的上传下载
 *
 * @author dsy
 *
 */
public class ContinueFtpUtils {
    private static final Logger logger = LoggerFactory
            .getLogger(ContinueFtpUtils.class);
    private FTPClient ftpClient = new FTPClient();

    public ContinueFtpUtils() {
        // 设置将过程中使用到的命令输出到控制台
        this.ftpClient.addProtocolCommandListener(new PrintCommandListener(
                new PrintWriter(System.out)));
    }

    /**
     * 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);
        if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
            if (ftpClient.login(username, password)) {
                return true;
            }
        }
        disconnect();
        return false;
    }

    /**
     * 从FTP服务器上下载文件
     *
     * @param remote
     *            远程文件路径
     * @param local
     *            本地文件路径
     * @return 是否成功
     * @throws IOException
     */
    @SuppressWarnings("resource")
    public boolean download(String remote, String local) throws IOException {
        ftpClient.enterLocalPassiveMode(); // 设置为被动模式
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        boolean result;
        // 从ftp获取文件
        String[] str = local.split("/");
        String localFilePath = local.replace("/" + str[str.length - 1], "")
                .trim();
        File file = new File(localFilePath);
        if (!file.isDirectory()) {
            file.mkdirs();
            logger.info("create new  file");
        }

        File f = new File(local);
        FTPFile[] files = ftpClient.listFiles(remote);
        if (files.length != 1) {
            logger.info(" The remote file is not the only {}");
            return false;
        }
        long lRemoteSize = files[0].getSize();
        if (f.exists()) {
            OutputStream out = new FileOutputStream(f, true);
            if (f.length() >= lRemoteSize) {
                logger.info(" The local file is greater than the remote file ,Download the stop{}");
                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
     */
    @SuppressWarnings("resource")
    public FtpStatusEnum upload(String local, String remote) throws IOException {
        // 设置PassiveMode传输
        ftpClient.enterLocalPassiveMode();
        // 设置以二进制流的方式传输
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        FtpStatusEnum 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 {
                            logger.info(" Failed to create the directory {}");
                            return FtpStatusEnum.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 FtpStatusEnum.FILE_EXITS;
            } else if (remoteSize > localSize) {
                return FtpStatusEnum.REMOTE_BIGGER_LOCAL;
            }

            // 尝试移动文件内读取指针,实现断点续传
            InputStream is = new FileInputStream(f);
            if (is.skip(remoteSize) == remoteSize) {
                ftpClient.setRestartOffset(remoteSize);
                if (ftpClient.storeFile(remote, is)) {
                    return FtpStatusEnum.UPLOAD_FROM_BREAK_SUCCESS;
                }
            }

            // 如果断点续传没有成功,则删除服务器上文件,重新上传
            if (!ftpClient.deleteFile(remoteFileName)) {
                return FtpStatusEnum.DELETE_REMOTE_FAILD;
            }
            is = new FileInputStream(f);
            if (ftpClient.storeFile(remote, is)) {
                result = FtpStatusEnum.UPLOAD_NEW_FILE_SUCCESS;
            } else {
                result = FtpStatusEnum.UPLOAD_NEW_FILE_FAILED;
            }
            is.close();
        } else {
            InputStream is = new FileInputStream(local);
            if (ftpClient.storeFile(remoteFileName, is)) {
                result = FtpStatusEnum.UPLOAD_NEW_FILE_SUCCESS;
            } else {
                result = FtpStatusEnum.UPLOAD_NEW_FILE_FAILED;
            }
            is.close();
        }
        return result;
    }

    /**
     * 断开与远程服务器的连接
     *
     * @throws IOException
     */
    public void disconnect() throws IOException {
        if (ftpClient.isConnected()) {
            ftpClient.disconnect();
        }
    }

}
0 0
原创粉丝点击