Java部分处理记录
1. FTP 中文文件名乱码与目录删除
在 Java 中使用 ftpClient.listFiles()
方法获取 Linux 服务器上的中文文件名时,经常会出现乱码问题。这是由于 FTP 协议在不同系统间的编码不一致导致的,Windows 系统通常使用 GBK 编码,而 Linux 系统多使用 UTF-8 编码。
- 编码探测机制:通过发送
OPTS UTF8 ON
命令检测服务器是否支持 UTF-8 编码 - 动态编码切换:根据服务器支持情况自动选择 GBK 或 UTF-8 编码
- 控制通道编码:通过
setControlEncoding()
方法设置控制通道的编码方式
/**
* 连接到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);
// 动态检测服务器编码支持
String charset = "gbk"; // 默认使用GBK编码
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
charset = "utf-8"; // 如果服务器支持UTF-8则切换编码
}
ftpClient.setControlEncoding(charset); // 设置控制通道编码
// 验证连接状态
if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
return ftpClient.login(username, password);
}
disconnect();
return false;
}
-
目录删除细节
-
使用
new String(pathName.getBytes("utf-8"), "iso-8859-1")
解决中文路径问题 -
确保递归调用时路径编码的一致性
-
Tomcat服务器中著名的URIEncoding配置问题:
<Connector port="8080" URIEncoding="UTF-8" />
当不配置URIEncoding时,Tomcat默认使用ISO-8859-1解码URL,导致:浏览器用UTF-8编码URL
Tomcat用ISO-8859-1解码出现中文乱码。 -
先删除目录下的所有文件和子目录,最后删除空目录本身
-
必须切换到父目录才能删除当前目录
/**
* 递归删除FTP服务器上的文件夹及其内容
* @param pathName 要删除的文件夹路径
*/
public void deleteDirectory(String pathName) {
try {
// 特殊编码处理获取文件列表
FTPFile[] files = ftpClient.listFiles(new String(pathName.getBytes("utf-8"), "iso-8859-1"));
if (files != null && files.length > 0) {
for (FTPFile file : files) {
String currentPath = pathName + "/" + file.getName();
if (file.isDirectory()) {
deleteDirectory(currentPath); // 递归删除子目录
} else {
// 删除文件需要特殊编码处理
if (!ftpClient.deleteFile(new String(currentPath.getBytes("utf-8"), "iso-8859-1"))) {
System.out.println(" 文件删除失败: " + currentPath);
}
}
}
}
// 切换到父目录后才能删除空文件夹
String parentPath = pathName.substring(0, pathName.lastIndexOf("/"));
ftpClient.changeWorkingDirectory(new String(parentPath.getBytes("utf-8"), "iso-8859-1"));
// 最终删除空文件夹
boolean removed = ftpClient.removeDirectory(new String(pathName.getBytes("utf-8"), "iso-8859-1"));
System.out.println(" 目录删除" + (removed ? "成功" : "失败") + ": " + pathName);
} catch (IOException e) {
e.printStackTrace();
}
}
2 IDEA 连接服务器 Docker
Docker服务配置:
# 进入Docker服务配置目录
cd /etc/systemd/system/multi-user.target.wants
# 编辑Docker服务配置文件
vim docker.service
# 追加以下内容允许远程连接
-H tcp://0.0.0.0:2375
# 重新加载并重启Docker服务
systemctl daemon-reload
systemctl restart docker
注意:
1. 0.0.0.0
表示监听所有网络接口,生产环境应限制IP访问
2. 2375 端口是未加密的Docker API端口,建议使用2376 TLS加密端口
3. 配置防火墙规则限制访问来源
3 Windows 路径兼容性问题
有这样一个需求:方便Windows用户在配置文件中手动更改选择文件路径,Windows中路径都是类似于:C:\Windows\Boot
反斜杠路径,而反斜杠在Java中的存在表示转移字符
。程序中的//双斜线、/单斜线、\\双反斜线,都能够识别路径,但\
反斜线不行。
- 使用正斜杠
/
:Java 可自动识别 - 使用双反斜杠
\\
:表示单个反斜杠 - 使用
File.separator
:系统无关的分隔符
配置文件示例 (config.properties):
重载load方法可以在读取时进行预处理:
import java.io.*;
import java.util.Objects;
import java.util.Properties;
/**
* 自定义Properties类处理Windows路径问题
*/
public class PathAwareProperties extends Properties {
@Override
public synchronized void load(Reader reader) throws IOException {
BufferedReader br = new BufferedReader(reader);
String line;
while ((line = br.readLine()) != null) {
// 处理BOM头
if (line.startsWith("\uFEFF")) {
line = line.substring(1);
}
// 跳过注释和空行
if (line.startsWith("#") || line.isEmpty()) {
continue;
}
// 分割键值对
String[] parts = line.split("=", 2);
if (parts.length == 2) {
// 转换路径分隔符并处理转义
String processedValue = parts[1]
.replaceAll("\\\\\\\\", "/") // 处理连续反斜杠
.replaceAll("\\\\ ", " "); // 处理路径中的空格
put(parts[0], processedValue);
}
}
}
public static void main(String[] args) throws IOException {
PathAwareProperties props = new PathAwareProperties();
props.load(new InputStreamReader(
new FileInputStream("src/main/resources/config.properties")));
System.out.println("testFile01Path: " + props.getProperty("testFile01Path"));
System.out.println("testFile02Path: " + props.getProperty("testFile02Path"));
}
}