doum
2026-06-11 d9c657aa78cf0ebe31933a87e63ca92edd8a8da3
server/system_service/src/main/java/com/doumee/core/utils/FtpUtil.java
@@ -1,6 +1,8 @@
package com.doumee.core.utils;
import java.io.*;
import java.net.MalformedURLException;
import java.util.Date;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
@@ -15,6 +17,7 @@
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.apache.xpath.operations.Bool;
import sun.misc.BASE64Encoder;
/** */
@@ -49,6 +52,37 @@
      FtpUtil.password =password;
      connect();
   }
   /**
    * 初始化ftp服务器
    */
   public boolean connect() {
      boolean flag = false;
      try {
         System.out.println("connecting...ftp服务器:"+this.hostname+":"+this.port);
         ftpClient.setRemoteVerificationEnabled(false);
         ftpClient.connect(hostname, port); //连接ftp服务器
         ftpClient.login(username, password); //登录ftp服务器
//            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
//               LOCAL_CHARSET = "UTF-8";
//         }
         ftpClient.setControlEncoding("GBK");
         ftpClient.enterLocalPassiveMode();
         int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
         if(!FTPReply.isPositiveCompletion(replyCode)){
            log.error("connect failed...ftp服务器:"+this.hostname+":"+this.port+"返回码:"+replyCode);
         }else {
            flag = true;
            log.info("connect successful...ftp服务器:"+this.hostname+":"+this.port+"返回码:"+replyCode);
         }
      }catch (MalformedURLException e) {
         e.printStackTrace();
         log.error("connect exception...ftp服务器:"+this.hostname+":"+this.port+   e.getMessage());
      }catch (IOException e) {
         e.printStackTrace();
         log.error("connect exception...ftp服务器:"+this.hostname+":"+this.port+   e.getMessage());
      }
      return flag;
   }
   /** */
   /**
@@ -58,7 +92,7 @@
    * @return 是否连接成功
    * @throws IOException
    */
   public boolean connect() throws IOException {
   public boolean connect2() throws IOException {
      ftpClient.connect(hostname, port);
      ftpClient.setControlEncoding("GBK");
      if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
@@ -235,9 +269,10 @@
   }
   public boolean uploadInputstream(InputStream inputStream, String remote)  {
      // 设置PassiveMode传输
      Date d1 = new Date();
      log.error("上传文件成功=============开始========="+DateUtil.getPlusTime2(d1));
      try {
         ftpClient.enterLocalPassiveMode();
         // 设置以二进制流的方式传输
         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
         ftpClient.setControlEncoding("GBK");
@@ -259,6 +294,8 @@
         }else{
            log.error("上传文件失败======================="+remote);
         }
         Date d2= new Date();
         log.error("上传文件成功=============结束========="+DateUtil.getPlusTime2(d2) +"耗时毫秒:"+( (d2.getTime()-d1.getTime())  ));
         return result;
      }catch (Exception e){
         e.printStackTrace();
@@ -266,6 +303,184 @@
      }
      return false;
   }
   /** 从 FTP 读取远程文件并写入输出流(用于在线预览/下载) */
   public boolean streamRemoteFile(String remote, OutputStream outputStream) throws IOException {
      if (streamRemoteFileInternal(remote, outputStream, 0, -1)) {
         return true;
      }
      if (remote.startsWith("/")) {
         return streamRemoteFileInternal(remote.substring(1), outputStream, 0, -1);
      }
      return streamRemoteFileByCwd(remote, outputStream, 0, -1);
   }
   /** 按字节范围从 FTP 读取远程文件(支持 MP4 分段播放) */
   public boolean streamRemoteFileRange(String remote, OutputStream outputStream, long start, long length) throws IOException {
      if (streamRemoteFileInternal(remote, outputStream, start, length)) {
         return true;
      }
      if (remote.startsWith("/")) {
         return streamRemoteFileInternal(remote.substring(1), outputStream, start, length);
      }
      return streamRemoteFileByCwd(remote, outputStream, start, length);
   }
   public long getRemoteFileSize(String remote) throws IOException {
      Long size = resolveRemoteFileSize(remote);
      if (size != null) {
         return size;
      }
      if (remote.startsWith("/")) {
         size = resolveRemoteFileSize(remote.substring(1));
      }
      return size != null ? size : -1L;
   }
   private Long resolveRemoteFileSize(String remote) throws IOException {
      String originalCwd = ftpClient.printWorkingDirectory();
      try {
         ftpClient.enterLocalPassiveMode();
         FTPFile[] files = ftpClient.listFiles(new String(remote.getBytes("GBK"), "iso-8859-1"));
         if (files != null && files.length == 1 && files[0].isFile()) {
            return files[0].getSize();
         }
         if (remote.contains("/")) {
            String directory = remote.substring(0, remote.lastIndexOf('/') + 1);
            String fileName = remote.substring(remote.lastIndexOf('/') + 1);
            if (ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"), "iso-8859-1"))) {
               files = ftpClient.listFiles(new String(fileName.getBytes("GBK"), "iso-8859-1"));
               if (files != null && files.length == 1 && files[0].isFile()) {
                  return files[0].getSize();
               }
            }
         }
         return null;
      } finally {
         if (originalCwd != null) {
            ftpClient.changeWorkingDirectory(originalCwd);
         }
      }
   }
   private boolean streamRemoteFileInternal(String remote, OutputStream outputStream, long start, long length) throws IOException {
      InputStream in = null;
      try {
         ftpClient.enterLocalPassiveMode();
         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
         if (start > 0) {
            ftpClient.setRestartOffset(start);
         }
         String encoded = new String(remote.getBytes("GBK"), "iso-8859-1");
         in = ftpClient.retrieveFileStream(encoded);
         if (in == null) {
            return false;
         }
         byte[] buffer = new byte[8192];
         long remaining = length;
         int len;
         while ((len = in.read(buffer)) != -1) {
            if (length >= 0 && remaining <= 0) {
               break;
            }
            int writeLen = len;
            if (length >= 0 && writeLen > remaining) {
               writeLen = (int) remaining;
            }
            outputStream.write(buffer, 0, writeLen);
            if (length >= 0) {
               remaining -= writeLen;
            }
         }
         outputStream.flush();
         return ftpClient.completePendingCommand();
      } finally {
         if (in != null) {
            in.close();
         }
      }
   }
   private boolean streamRemoteFileByCwd(String remote, OutputStream outputStream, long start, long length) throws IOException {
      if (!remote.contains("/")) {
         return false;
      }
      String directory = remote.substring(0, remote.lastIndexOf('/') + 1);
      String fileName = remote.substring(remote.lastIndexOf('/') + 1);
      ftpClient.enterLocalPassiveMode();
      ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
      if (!ftpClient.changeWorkingDirectory(new String(directory.getBytes("GBK"), "iso-8859-1"))) {
         return false;
      }
      if (start > 0) {
         ftpClient.setRestartOffset(start);
      }
      InputStream in = null;
      try {
         in = ftpClient.retrieveFileStream(new String(fileName.getBytes("GBK"), "iso-8859-1"));
         if (in == null) {
            return false;
         }
         byte[] buffer = new byte[8192];
         long remaining = length;
         int len;
         while ((len = in.read(buffer)) != -1) {
            if (length >= 0 && remaining <= 0) {
               break;
            }
            int writeLen = len;
            if (length >= 0 && writeLen > remaining) {
               writeLen = (int) remaining;
            }
            outputStream.write(buffer, 0, writeLen);
            if (length >= 0) {
               remaining -= writeLen;
            }
         }
         outputStream.flush();
         return ftpClient.completePendingCommand();
      } finally {
         if (in != null) {
            in.close();
         }
      }
   }
   public boolean uploadInputstreamBatch(InputStream inputStream, String remote, Boolean close , Integer index )  {
      // 设置PassiveMode传输
      try {
         ftpClient.enterLocalPassiveMode();
         // 设置以二进制流的方式传输
         ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
         ftpClient.setControlEncoding("GBK");
         // 对远程目录的处理
         String remoteFileName = remote;
         if (remote.contains("/")) {
            remoteFileName = remote.substring(remote.lastIndexOf("/") + 1);
            // 创建服务器远程目录结构,创建失败直接返回
            if (Constants.equalsInteger(index,Constants.ONE) && StringUtils.equals(CreateDirecroty(remote, ftpClient), "2")) {
               log.error("创建ftp目录失败======================="+remote);
               return false;
            }
         }
         boolean result = ftpClient.storeFile(remoteFileName, inputStream);
         inputStream.close();
         if(close){
            ftpClient.logout();
         }
         if(result){
            log.info("上传文件成功======================"+remote);
         }else{
            log.error("上传文件失败======================="+remote);
         }
         return result;
      }catch (Exception e){
         e.printStackTrace();
         log.error("上传文件失败======================="+remote);
      }
      return false;
   }
   public int getNumFromStr(String str,char searchstr) {
      int count = 0;
      char[] charArray = str.toCharArray();
@@ -540,8 +755,8 @@
   public static void main(String[] args) throws Exception {
      try {
         FtpUtil ftpUtil = new FtpUtil("175.27.187.84", 21, "ftpuser","doumee168" );
         ftpUtil.uploadOnlineFile("https://profile-avatar.csdnimg.cn/default.jpg!1", "test"+"/", UUID.randomUUID().toString()+"test.jpg");
         FtpUtil ftpUtil = new FtpUtil("192.168.0.7", 21, "uftp","doumee@168" );
         ftpUtil.uploadOnlineFile("https://profile-avatar.csdnimg.cn/default.jpg!1", "member"+"/20251229/", UUID.randomUUID().toString()+"test.jpg");
         /*FtpUtil myFtp = new FtpUtil("106.15.54.228", 21, "ftptlg",
               "tlg168.com");
         System.out.println(myFtp.upload("D:\\devices.sql", "/1111/devices.sql"));