ftp文件的断点上传工具类


/**
 * 将文件上传至ftp服务器
 */
public class FtpUtils {

    private static Logger logger = Logger.getLogger(FtpUtils.class);
    public static FTPClient ftpClient = new FTPClient();

    /**
     * 初始化ftp服务器,连接ftp服务器
     *
     * @param hostname ftp IP
     * @param port     ftp 端口
     * @param username 用户名
     * @param password 密码
     */
    public void initFtpClient(String hostname, Integer port, String username, String password) {

        try {
            ftpClient.setControlEncoding("utf-8");
            System.out.println("connecting...ftp服务器:" + hostname + "," + port);
            //链接服务器
            ftpClient.connect(hostname, port);
            //登录服务器
            ftpClient.login(username, password);
            //判断是否成功登录服务器
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                logger.error("connect failed...ftp服务器");
            } else {
                logger.info("connect success...ftp服务器");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 递归创建远程服务器目录
     *
     * @param ftpPath   上传文件的存放路径
     * @param ftpClient 本地源文件路径
     * @return
     * @throws Exception
     */
    private static upLoadStatus CreateDirectory(String ftpPath, FTPClient ftpClient) throws Exception {
        upLoadStatus status = upLoadStatus.Create_Directory_Success;
        String directory = ftpPath.substring(0, ftpPath.lastIndexOf("/") + 1);
        if (directory.equalsIgnoreCase("/") && ftpClient.changeWorkingDirectory(new String(directory.getBytes("UTF-8")))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            while (true) {
                String subDirectory = new String(ftpPath.substring(start, end).getBytes("UTF-8"), "UTF-8");
                if (!ftpClient.changeWorkingDirectory(subDirectory)) {
                    if (ftpClient.makeDirectory(subDirectory)) {
                        ftpClient.changeWorkingDirectory(subDirectory);
                    } else {
                        logger.error("创建目录失败");
                        return upLoadStatus.Create_Directory_Fail;
                    }

                }
                start = end + 1;
                end = directory.indexOf("/", start);
                if (end <= start) {
                    break;
                }
            }
        }
        logger.info("创建目录成功");
        return status;
    }

    /**
     * 文件的上传
     *
     * @param ftpPath     ftp文件上传的保存路径
     * @param inputStream 本地文件路径
     * @return
     */

    public static upLoadStatus upload(String inputStream, String ftpPath) throws Exception {
        try {
            //设置passiveMode传输
            ftpClient.enterLocalPassiveMode();
            logger.info("开始上传文件");
            //二进制方式保存文件
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            ftpClient.setControlEncoding("UTF-8");
            upLoadStatus result;
            //对远程目录的处理
            String ftpFileName = ftpPath;
            if (ftpPath.contains("/")) {
                ftpFileName = ftpPath.substring(ftpPath.lastIndexOf("/") + 1);
                if (CreateDirectory(ftpPath, ftpClient) == upLoadStatus.Create_Directory_Fail) {
                    logger.error("创建目录失败");
                    return upLoadStatus.Create_Directory_Fail;
                }

                FTPFile[] files = ftpClient.listFiles(new String(ftpFileName.getBytes("UTF-8"), "UTF-8"));
                if (files.length == 1) {
                    long remoteSize = files[0].getSize();
                    File f = new File(inputStream);
                    long localSize = f.length();
                    if (remoteSize == localSize) {
                        logger.info("文件已经存在");
                        return upLoadStatus.File_Exits;
                    } else if (remoteSize > localSize) {
                        logger.info("远程文件大小大于本地文件大小");
                        return upLoadStatus.Remote_Bigger_Local;
                    }
                    result = uploadFile(ftpFileName, f, ftpClient, remoteSize);

                    if (result == upLoadStatus.Upload_Form_Break_Failed) {
                        if (!ftpClient.deleteFile(ftpFileName)) {
                            logger.error("远程文件删除失败");
                            return upLoadStatus.Delete_Remote_Failed;
                        }
                        result = uploadFile(ftpFileName, f, ftpClient, 0);
                    }
                } else {
                    result = uploadFile(ftpFileName, new File(inputStream), ftpClient, 0);
                }
                logger.info("文件上传成功");
                return result;
            }

        } catch (Exception e) {
            logger.error("上传文件失败");
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 文件的断点上传
     * @param ftpFile 远程文件存放目录
     * @param localFile 本地文件存放目录
     * @param ftpClient
     * @param remoteSize 已经上传文件的字节大小
     * @return
     * @throws Exception
     */

    public static upLoadStatus uploadFile(String ftpFile, File localFile, FTPClient ftpClient, long remoteSize) throws Exception {
        upLoadStatus status;
        long step = localFile.length() / 100;
        long process = 0;
        long localreadBytes = 0L;
        RandomAccessFile randomAccessFile = new RandomAccessFile(localFile, "r");
        OutputStream out = ftpClient.appendFileStream(new String(ftpFile.getBytes("UTF-8"), "UTF-8"));
        try {
            if (remoteSize > 0) {
                ftpClient.setRestartOffset(remoteSize);
                process = remoteSize / step;
                randomAccessFile.seek(remoteSize);
                localreadBytes = remoteSize;
            }
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }

        byte[] bytes = new byte[1024];
        int c;
        while ((c = randomAccessFile.read(bytes)) != -1) {
            out.write(bytes, 0, c);
            localreadBytes += c;
            if (step != 0) {
                if (localreadBytes / step != process) {
                    process = localreadBytes / step;
                    logger.info("上传进度" + process);
                }
            }
        }
        out.flush();
        randomAccessFile.close();
        out.close();
        boolean result = ftpClient.completePendingCommand();
        if (remoteSize > 0) {
            status = result ? upLoadStatus.Upload_Form_Break_Success : upLoadStatus.Upload_Form_Break_Failed;
        } else {
            status = result ? upLoadStatus.Upload_NewFile_Success : upLoadStatus.Upload_NewFile_Failed;
        }
        return status;
    }
}

注意:upLoadStatus是自己写的一个枚举类。这个工具类是在看了无数博文之后参考,应用到项目中并测试成功的类,记录下来,当做工具类使用。

猜你喜欢

转载自blog.csdn.net/hqm12345qw/article/details/79806924