双ftp搭建

本文介绍如何使用Apache Commons Net库实现FTP连接,登录、文件内容MD5校验,并演示了如何在上传文件的同时生成和验证MD5。重点讲解了如何通过递归处理文件夹结构和生成加盐或普通方式的MD5哈希。
摘要由CSDN通过智能技术生成

ftp搭建

package com.key.win.utils;

/**
 * @ClassName Md5Utils
 * @Description TODO
 * @Date 2020/11/18 15:30
 * @Version 1.0
 */

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Slf4j
public class DoubleFtpUtils {
    protected static char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6',
            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    protected static MessageDigest messagedigest = null;
    static {
        try {
            // 获得MD5摘要算法的 MessageDigest 对象
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsaex) {
            log.info(DoubleFtpUtils.class.getName() + "初始化失败,MessageDigest不支持MD5Util。");
            nsaex.printStackTrace();
        }
    }

    //登陆
    public static FTPClient login(String url, int port, String username, String password) {

        FTPClient ftpClient = new FTPClient();

        try {
            if (!ftpClient.isConnected()) {
                ftpClient.connect(url, port);
                ftpClient.login(username, password);// 登录
                ftpClient.enterLocalActiveMode();
                //  ftp.enterLocalPassiveMode();
                ftpClient.setRemoteVerificationEnabled(false);
                ftpClient.setBufferSize(100000);
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                log.info(url + "ftpClient receive code " + ftpClient.getReplyCode() + " success");
            }
        } catch (IOException e) {
            e.printStackTrace();
            log.info("ftpClient receive code " + ftpClient.getReplyCode() + " fault");
        }
        return ftpClient;

    }


    /**
     * 生成文件的md5校验值
     * 注意:FTPClient如果使用到输入流或者输出流,必须使用completePendingCommand,否则文件内容写入会为null
     *
     * @param
     * @return
     * @throws IOException
     */
    public static String getFileMD5String(InputStream inputStream, FTPClient goalFtp) throws IOException {

        byte[] buffer = new byte[1024];
        int numRead = 0;
        while ((numRead = inputStream.read(buffer)) > 0) {
            messagedigest.update(buffer, 0, numRead);
        }
        inputStream.close();
        goalFtp.completePendingCommand();
        byte bytes[] = messagedigest.digest();
        int j = bytes.length;

        char str[] = new char[j * 2];
        int k = 0;
        for (int i = 0; i < j; i++) {
            byte byte0 = bytes[i];
            str[k++] = hexDigits[byte0 >>> 4 & 0xf];// 取字节中高 4 位的数字转换, >>>
            // 为逻辑右移,将符号位一起右移,此处未发现两种符号有何不同
            str[k++] = hexDigits[byte0 & 0xf];// 取字节中低 4 位的数字转换
        }
        return new String(str);
    }


    /**
     * 生成32位md5码
     * 加盐方式
     *
     * @param password
     * @return
     */
    public static String md5Password(String password) {

        byte[] result = messagedigest.digest(password.getBytes());
        StringBuffer buffer = new StringBuffer();
        // 把每一个byte 做一个与运算 0xff;
        for (byte b : result) {
            // 与运算
            int number = b & 0xff;// 加盐
            String str = Integer.toHexString(number);
            if (str.length() == 1) {
                buffer.append("0");
            }
            buffer.append(str);
        }

        // 标准的md5加密后的结果
        return buffer.toString();
    }

    /**
     * 生成32位md5码
     * 普通方式
     *
     * @param key
     * @return
     */
    public static String MD5(String key) {
        try {
            byte[] btInput = key.getBytes();

            // 使用指定的字节更新摘要
            messagedigest.update(btInput);
            // 获得密文
            byte[] md = messagedigest.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

    /*
     * @Description TODO
     * @Date 2021/4/12
     * @param sourceFtp   源ftp
     * @param sourcePath  源ftp路径
     * @param goalFtp    goalFtp目标ftp
     * @param goalPath   目标ftp路径
     * @param bornMd5   是否生成MD5加密文件
     * @return void
     */
    public static void sendDoubleFtpContent(FTPClient sourceFtp, String sourcePath, FTPClient goalFtp, String goalPath, Boolean bornMd5) {
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            sendContentMd5(sourceFtp, sourcePath, goalFtp, goalPath, bornMd5, inputStream, outputStream);
            if (outputStream != null) {
                outputStream.flush();
                outputStream.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
            //关闭发送文件的服务器ftp
            if (sourceFtp.isConnected()) {
                sourceFtp.disconnect();
                log.info("退出第三方发送文件的FTP完成");
            }
            if (goalFtp.isConnected()) {
                goalFtp.disconnect();
                log.info("关闭接受文件的ftp并创建好文件夹");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    private static void sendContentMd5(FTPClient sourceFtp, String sourcePath, FTPClient goalFtp, String goalPath, Boolean bornMd5, InputStream inputStream, OutputStream outputStream) {
        //发送文件的ftp切换工作路径
        try {
            sourceFtp.changeWorkingDirectory(sourcePath);

            //获取所有文件
            FTPFile target[] = sourceFtp.listFiles();
            //遍历发送文件的ftp的文件是否是文件夹
            for (FTPFile q : target) {
                //接收方的ftp上创建好相应的文件夹
                if (q.isDirectory()) {
                    //切换接收方的工作目录
                    goalFtp.changeWorkingDirectory(goalPath);
                    //在接收方的工作目录下创建目录文件
                    goalFtp.makeDirectory(q.getName());
                    //递归遍历
                    sendContentMd5(sourceFtp, sourcePath + "/" + q.getName(), goalFtp, goalPath + "/" + q.getName(), bornMd5, inputStream, outputStream);
                } else {
                    //切换工作路径
                    goalFtp.changeWorkingDirectory(goalPath);
                    //复制文件
                    outputStream = goalFtp.storeFileStream(goalFtp.printWorkingDirectory() + "/" + q.getName());

                    //写入文件
                    Boolean b = sourceFtp.retrieveFile(q.getName(), outputStream);
                    if (outputStream != null) {
                        outputStream.flush();
                        outputStream.close();
                        goalFtp.completePendingCommand();
                        log.info("ftp同步文件完成___" + q.getName());
                    }
                    if (bornMd5) {
                        //转换成输入流
                        inputStream = goalFtp.retrieveFileStream(goalFtp.printWorkingDirectory() + "/" + q.getName());
                        //MD5密文
                        String md5Secret = DoubleFtpUtils.getFileMD5String(inputStream, goalFtp);

                        inputStream = new ByteArrayInputStream(md5Secret.getBytes("utf-8"));
                        goalFtp.changeWorkingDirectory(goalFtp.printWorkingDirectory() + "/" + q.getName() + ".md5");
                        goalFtp.storeFile(q.getName() + ".md5", inputStream);
                        if (inputStream != null) {
                            inputStream.close();
                            log.info("md5密文写入完成___" + q.getName() + ".md5");
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
<!--ftp依赖 -->
		<dependency>
			<groupId>commons-net</groupId>
			<artifactId>commons-net</artifactId>
		</dependency>
		<!--md5加密算法 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
		</dependency>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值