Browse Source

Window FTP服务器上下载带中文的文件结果为空

dimples 5 years ago
parent
commit
b13ec78f61

+ 59 - 11
hutool-extra/src/main/java/cn/hutool/extra/ftp/Ftp.java

@@ -1,13 +1,7 @@
 package cn.hutool.extra.ftp;
 
-import cn.hutool.core.collection.ListUtil;
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.lang.Filter;
-import cn.hutool.core.util.ArrayUtil;
-import cn.hutool.core.util.CharsetUtil;
-import cn.hutool.core.util.StrUtil;
 import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPClientConfig;
 import org.apache.commons.net.ftp.FTPFile;
 import org.apache.commons.net.ftp.FTPReply;
 
@@ -16,9 +10,18 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.lang.Filter;
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+
 /**
  * FTP客户端封装<br>
  * 此客户端基于Apache-Commons-Net
@@ -81,7 +84,22 @@ public class Ftp extends AbstractFtp {
 	 * @param charset  编码
 	 */
 	public Ftp(String host, int port, String user, String password, Charset charset) {
-		this(host, port, user, password, charset, null);
+		this(host, port, user, password, charset,null, null, null);
+	}
+
+	/**
+	 * 构造
+	 *
+	 * @param host     域名或IP
+	 * @param port     端口
+	 * @param user     用户名
+	 * @param password 密码
+	 * @param charset  编码
+	 * @param serverLanguageCode 服务器语言 例如:zh
+	 * @param systemKey 服务器标识 例如:org.apache.commons.net.ftp.FTPClientConfig.SYST_NT
+	 */
+	public Ftp(String host, int port, String user, String password, Charset charset, String serverLanguageCode, String systemKey) {
+		this(host, port, user, password, charset, serverLanguageCode, systemKey, null);
 	}
 
 	/**
@@ -94,8 +112,8 @@ public class Ftp extends AbstractFtp {
 	 * @param charset  编码
 	 * @param mode     模式
 	 */
-	public Ftp(String host, int port, String user, String password, Charset charset, FtpMode mode) {
-		this(new FtpConfig(host, port, user, password, charset), mode);
+	public Ftp(String host, int port, String user, String password, Charset charset, String serverLanguageCode, String systemKey, FtpMode mode) {
+		this(new FtpConfig(host, port, user, password, charset, serverLanguageCode, systemKey), mode);
 	}
 
 	/**
@@ -143,7 +161,7 @@ public class Ftp extends AbstractFtp {
 	 * @return this
 	 */
 	public Ftp init(String host, int port, String user, String password, FtpMode mode) {
-		return init(new FtpConfig(host, port, user, password, this.ftpConfig.getCharset()), mode);
+		return init(new FtpConfig(host, port, user, password, this.ftpConfig.getCharset(), null, null), mode);
 	}
 
 	/**
@@ -161,6 +179,11 @@ public class Ftp extends AbstractFtp {
 			// 连接ftp服务器
 			client.connect(config.getHost(), config.getPort());
 			client.setSoTimeout((int) config.getSoTimeout());
+			// 下载中文文件
+			if (StrUtil.isNotBlank(config.getSystemKey()) && StrUtil.isNotBlank(config.getServerLanguageCode())){
+				FTPClientConfig conf = new FTPClientConfig(config.getSystemKey());
+				conf.setServerLanguageCode(config.getServerLanguageCode());
+			}
 			// 登录ftp服务器
 			client.login(config.getUser(), config.getPassword());
 		} catch (IOException e) {
@@ -597,6 +620,31 @@ public class Ftp extends AbstractFtp {
 		}
 	}
 
+    /**
+     * 下载文件到输出流
+     *
+     * @param path     文件路径
+     * @param fileName 文件名
+     * @param out      输出位置
+     */
+    public void download(String path, String fileName, OutputStream out, String fileNameCharset) {
+        String pwd = null;
+        if (this.backToPwd) {
+            pwd = pwd();
+        }
+
+        cd(path);
+        try {
+            client.setFileType(FTPClient.BINARY_FILE_TYPE);
+            client.retrieveFile(new String(fileName.getBytes(fileNameCharset), StandardCharsets.ISO_8859_1), out);
+        } catch (IOException e) {
+            throw new FtpException(e);
+        } finally {
+            if (backToPwd) {
+                cd(pwd);
+            }
+        }
+    }
 	/**
 	 * 获取FTPClient客户端对象
 	 *

+ 32 - 1
hutool-extra/src/main/java/cn/hutool/extra/ftp/FtpConfig.java

@@ -46,6 +46,17 @@ public class FtpConfig implements Serializable {
 	 */
 	private long soTimeout;
 
+    /**
+     * 设置服务器语言
+     */
+	private String serverLanguageCode;
+
+    /**
+     * 设置服务器系统关键词
+     * @see org.apache.commons.net.ftp.FTPClientConfig
+     */
+    private String systemKey;
+
 	/**
 	 * 构造
 	 */
@@ -61,12 +72,14 @@ public class FtpConfig implements Serializable {
 	 * @param password 密码
 	 * @param charset 编码
 	 */
-	public FtpConfig(String host, int port, String user, String password, Charset charset) {
+	public FtpConfig(String host, int port, String user, String password, Charset charset, String serverLanguageCode, String systemKey) {
 		this.host = host;
 		this.port = port;
 		this.user = user;
 		this.password = password;
 		this.charset = charset;
+		this.serverLanguageCode = serverLanguageCode;
+		this.systemKey = systemKey;
 	}
 
 	public String getHost() {
@@ -131,4 +144,22 @@ public class FtpConfig implements Serializable {
 		this.soTimeout = soTimeout;
 		return this;
 	}
+
+	public String getServerLanguageCode() {
+		return serverLanguageCode;
+	}
+
+	public FtpConfig setServerLanguageCode(String serverLanguageCode) {
+		this.serverLanguageCode = serverLanguageCode;
+		return this;
+	}
+
+	public String getSystemKey() {
+		return systemKey;
+	}
+
+	public FtpConfig setSystemKey(String systemKey) {
+		this.systemKey = systemKey;
+		return this;
+	}
 }