时间:2026-01-28 14:34
人气:
作者:admin
在上传图片系统中,当用户使用苹果本(Mac)压缩并上传目录时,系统出现异常。经过排查发现,Mac 系统在压缩时会自动生成大量隐藏文件和元数据目录,这些"垃圾文件"在解压后会干扰系统的正常业务逻辑。
这些文件在 Mac 环境下是正常的,但在上传到图片系统后会导致:
通过 Claude Code AI 助手 的协助,按照以下步骤定位和解决问题:
__MACOSX 元数据目录位置:src/main/java/net/shopin/pz/util/DeleteForder.java
deleteMacHiddenFiles(File directory)/**
* 删除Mac系统压缩时产生的隐藏文件和目录
* @param directory 需要清理的目录
*/
public static void deleteMacHiddenFiles(File directory) {
// 1. 参数校验
if (directory == null || !directory.exists() || !directory.isDirectory()) {
return;
}
// 2. 递归遍历目录
for (File file : directory.listFiles()) {
String fileName = file.getName();
// 3. 删除以 . 开头的隐藏文件(.DS_Store、._*等)
if (fileName.startsWith(".")) {
if (file.isDirectory()) {
recurDelete(file); // 递归删除目录
} else {
file.delete(); // 直接删除文件
}
continue;
}
// 4. 删除 __MACOSX 元数据目录(双重保险)
if ("__MACOSX".equalsIgnoreCase(fileName)) {
recurDelete(file);
continue;
}
// 5. 递归处理子目录
if (file.isDirectory()) {
deleteMacHiddenFiles(file);
}
}
}
清理逻辑:
. 开头的隐藏文件和目录(覆盖 .DS_Store、._* 等)__MACOSX 目录(双重保险)位置:/controller/FileUploadController.java
//解压zip文件结束
logger.info("解压文件" + file.getOriginalFilename() + "结束");
// ✅ 新增:清理Mac系统压缩产生的隐藏文件
try {
logger.info("跟踪信息" + uuid + "--清理Mac隐藏文件-:[" + shopName + "-" + planCreatedTime + "-" + photoTitle + "]<" + username + ">");
DeleteForder.deleteMacHiddenFiles(picDir); // 调用清理方法
logger.info("清理Mac隐藏文件完成");
} catch (Exception e) {
logger.error("清理Mac隐藏文件时出现异常:" + e);
e.printStackTrace();
}
//目录遍历
//... 后续业务逻辑
位置:/util/ZipLinuxUtil.java
/**
* 解压ZIP文件(自动检测编码,兼容Mac和Windows)
*/
public static void unzip(String sourceZip, String destDir) throws Exception {
try {
// 第一次尝试:自动检测编码解压
unzipWithDetectedEncoding(sourceZip, destDir);
} catch (Exception e) {
// 如果失败,尝试用UTF-8编码重试(兼容Mac系统压缩的文件)
logger.warn("第一次解压失败,尝试使用UTF-8编码重试:" + e.getMessage());
try {
unzipWithEncoding(sourceZip, destDir, "UTF-8");
logger.info("使用UTF-8编码重试成功");
} catch (Exception ex) {
logger.error("使用UTF-8编码重试也失败:" + ex.getMessage());
throw e; // 抛出原始异常
}
}
}
在提交中进一步完善:
File.listFiles() 返回 null 时的安全处理delete() 操作都检查返回值,失败时记录警告日志null 时使用默认编码(GBK)// 示例:安全删除操作
File[] files = f.listFiles();
if (files == null) {
// listFiles()返回null可能是权限问题或IO错误
boolean deleted = f.delete();
if (!deleted) {
logger.warn("无法删除文件或目录(可能无权限或目录非空):" + f.getPath());
}
return;
}
| 对比项 | 修复前 | 修复后 |
|---|---|---|
| Mac 垃圾文件 | ❌ 被当作正常图片处理,导致业务错误 | ✅ 自动清理,不影响业务逻辑 |
| ZIP 解压编码 | ❌ Mac 压缩文件解压失败 | ✅ 兼容 Mac(UTF-8)和 Windows(GBK) |
| null 值处理 | ❌ 可能导致空指针异常 | ✅ 全面的 null 检查和降级处理 |
| 错误日志 | ❌ 删除失败无提示 | ✅ 详细的警告和错误日志 |
修复后,在 Mac 系统上进行完整测试:
__MACOSX 目录被自动删除.DS_Store 等隐藏文件被自动删除._* 元数据文件被自动删除File.listFiles() 可能返回 null(权限问题、不是目录、IO错误)File.delete() 要检查返回值,判断是否真正删除成功deleteMacHiddenFiles 方法发布时间:2026-01-28 | 分类:跨平台兼容性 | 标签:Mac、Java、文件操作、ZIP压缩、垃圾文件清理