ImageCompressUtils.java 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. package com.ruoyi.app.utils;
  2. import com.ruoyi.common.config.RuoYiConfig;
  3. import com.ruoyi.common.constant.Constants;
  4. import com.ruoyi.common.utils.StringUtils;
  5. import net.coobird.thumbnailator.Thumbnails;
  6. import org.slf4j.Logger;
  7. import org.slf4j.LoggerFactory;
  8. import java.io.File;
  9. import java.io.IOException;
  10. import java.nio.file.Paths;
  11. /**
  12. * 图片压缩工具类 - 使用Thumbnailator实现
  13. *
  14. * @author ruoyi
  15. */
  16. public class ImageCompressUtils {
  17. private static final Logger log = LoggerFactory.getLogger(ImageCompressUtils.class);
  18. /**
  19. * 目标文件大小(200KB)
  20. */
  21. private static final long TARGET_SIZE = 100 * 1024; // 200KB = 200 * 1024 字节
  22. /**
  23. * 压缩图片 - 根据Web访问路径
  24. *
  25. * @param webPath Web访问路径 (如: /profile/upload/2025/08/05/image.jpg)
  26. * @return 压缩后的Web访问路径,如果不需要压缩则返回原路径
  27. */
  28. public static String compressImageByWebPath(String webPath) {
  29. log.info("开始处理Web路径图片压缩: {}", webPath);
  30. System.out.println("开始处理Web路径图片压缩: " + webPath);
  31. if (StringUtils.isEmpty(webPath)) {
  32. log.warn("Web路径为空,直接返回");
  33. System.out.println("Web路径为空,直接返回");
  34. return webPath;
  35. }
  36. try {
  37. // 将Web路径转换为本地文件路径
  38. String localPath = convertWebPathToLocalPath(webPath);
  39. log.debug("Web路径转换为本地路径: {} -> {}", webPath, localPath);
  40. System.out.println("Web路径转换为本地路径: " + webPath + " -> " + localPath);
  41. if (StringUtils.isEmpty(localPath)) {
  42. log.warn("无法转换Web路径到本地路径");
  43. System.out.println("无法转换Web路径到本地路径");
  44. return webPath;
  45. }
  46. File originalFile = new File(localPath);
  47. if (!originalFile.exists() || !originalFile.isFile()) {
  48. log.warn("文件不存在或不是文件: {}", localPath);
  49. System.out.println("文件不存在或不是文件: " + localPath);
  50. return webPath;
  51. }
  52. // 如果文件小于等于200KB,直接返回原路径
  53. if (originalFile.length() <= TARGET_SIZE) {
  54. log.info("文件大小 {} 字节,小于等于目标大小,无需压缩", originalFile.length());
  55. System.out.println("文件大小 " + originalFile.length() + " 字节,小于等于目标大小,无需压缩");
  56. return webPath;
  57. }
  58. // 生成压缩后的本地文件路径
  59. String compressedLocalPath = generateCompressedLocalPath(localPath);
  60. log.debug("生成压缩后本地路径: {}", compressedLocalPath);
  61. System.out.println("生成压缩后本地路径: " + compressedLocalPath);
  62. // 执行压缩
  63. log.info("开始压缩图片: {} -> {}", localPath, compressedLocalPath);
  64. System.out.println("开始压缩图片: " + localPath + " -> " + compressedLocalPath);
  65. if (compressImageWithThumbnailator(localPath, compressedLocalPath)) {
  66. // 将压缩后的本地路径转换为Web访问路径
  67. String compressedWebPath = convertLocalPathToWebPath(compressedLocalPath);
  68. // String compressedWebPath = compressedLocalPath;
  69. log.info("图片压缩成功: {} -> {}", webPath, compressedWebPath);
  70. System.out.println("图片压缩成功: " + webPath + " -> " + compressedWebPath);
  71. return compressedWebPath;
  72. } else {
  73. log.warn("图片压缩失败,返回原始路径: {}", webPath);
  74. System.out.println("图片压缩失败,返回原始路径: " + webPath);
  75. return webPath;
  76. }
  77. } catch (Exception e) {
  78. log.error("处理Web路径图片压缩时发生异常: " + webPath, e);
  79. System.err.println("处理Web路径图片压缩时发生异常: " + webPath + ", 错误: " + e.getMessage());
  80. e.printStackTrace();
  81. return webPath;
  82. } finally {
  83. // 建议垃圾回收
  84. System.gc();
  85. }
  86. }
  87. /**
  88. * 压缩图片 - 根据本地文件路径
  89. *
  90. * @param localPath 本地文件路径
  91. * @return 压缩后的本地文件路径,如果不需要压缩则返回原路径
  92. */
  93. public static String compressImageByLocalPath(String localPath) {
  94. log.info("开始处理本地路径图片压缩: {}", localPath);
  95. System.out.println("开始处理本地路径图片压缩: " + localPath);
  96. if (StringUtils.isEmpty(localPath)) {
  97. log.warn("本地路径为空,直接返回");
  98. System.out.println("本地路径为空,直接返回");
  99. return localPath;
  100. }
  101. File originalFile = new File(localPath);
  102. if (!originalFile.exists() || !originalFile.isFile()) {
  103. log.warn("文件不存在或不是文件: {}", localPath);
  104. System.out.println("文件不存在或不是文件: " + localPath);
  105. return localPath;
  106. }
  107. // 如果文件小于等于200KB,直接返回原路径
  108. if (originalFile.length() <= TARGET_SIZE) {
  109. log.info("文件大小 {} 字节,小于等于目标大小 {} 字节,无需压缩", originalFile.length(), TARGET_SIZE);
  110. System.out.println("文件大小 " + originalFile.length() + " 字节,小于等于目标大小 " + TARGET_SIZE + " 字节,无需压缩");
  111. return localPath;
  112. }
  113. try {
  114. // 生成压缩后的文件路径
  115. String compressedPath = generateCompressedLocalPath(localPath);
  116. log.debug("生成压缩后路径: {}", compressedPath);
  117. System.out.println("生成压缩后路径: " + compressedPath);
  118. // 执行压缩
  119. log.info("开始压缩图片: {} -> {}", localPath, compressedPath);
  120. System.out.println("开始压缩图片: " + localPath + " -> " + compressedPath);
  121. if (compressImageWithThumbnailator(localPath, compressedPath)) {
  122. log.info("本地图片压缩成功: {} -> {}", localPath, compressedPath);
  123. System.out.println("本地图片压缩成功: " + localPath + " -> " + compressedPath);
  124. return compressedPath;
  125. } else {
  126. log.warn("本地图片压缩失败,返回原始路径: {}", localPath);
  127. System.out.println("本地图片压缩失败,返回原始路径: " + localPath);
  128. return localPath;
  129. }
  130. } catch (Exception e) {
  131. log.error("处理本地路径图片压缩时发生异常: " + localPath, e);
  132. System.err.println("处理本地路径图片压缩时发生异常: " + localPath + ", 错误: " + e.getMessage());
  133. e.printStackTrace();
  134. return localPath;
  135. } finally {
  136. System.gc();
  137. }
  138. }
  139. /**
  140. * 压缩图片 - 简单方法,传入图片路径,返回压缩后的路径
  141. *
  142. * @param imagePath 图片路径
  143. * @return 压缩后的图片路径,如果不需要压缩则返回原路径
  144. */
  145. public static String compressImage(String imagePath) {
  146. log.info("开始压缩图片: {}", imagePath);
  147. System.out.println("开始压缩图片: " + imagePath);
  148. if (StringUtils.isEmpty(imagePath)) {
  149. log.warn("图片路径为空");
  150. System.out.println("图片路径为空");
  151. return imagePath;
  152. }
  153. // 检查文件是否存在
  154. File imageFile = new File(imagePath);
  155. if (!imageFile.exists() || !imageFile.isFile()) {
  156. log.warn("图片文件不存在: {}", imagePath);
  157. System.out.println("图片文件不存在: " + imagePath);
  158. return imagePath;
  159. }
  160. // 获取文件大小
  161. long fileSize = imageFile.length();
  162. long fileSizeKB = fileSize / 1024;
  163. log.info("图片文件大小: {} 字节 ({} KB)", fileSize, fileSizeKB);
  164. System.out.println("图片文件大小: " + fileSize + " 字节 (" + fileSizeKB + " KB)");
  165. // 如果文件小于等于200KB,直接返回原路径
  166. if (fileSize <= TARGET_SIZE) {
  167. log.info("文件大小 {} KB,小于等于200KB,无需压缩", fileSizeKB);
  168. System.out.println("文件大小 " + fileSizeKB + " KB,小于等于200KB,无需压缩");
  169. return imagePath;
  170. }
  171. log.info("文件大小 {} KB,大于200KB,开始压缩", fileSizeKB);
  172. System.out.println("文件大小 " + fileSizeKB + " KB,大于200KB,开始压缩");
  173. // 调用本地路径压缩方法
  174. return compressImageByLocalPath(imagePath);
  175. }
  176. /**
  177. * 将Web访问路径转换为本地文件路径
  178. *
  179. * @param webPath Web路径 (如: /profile/upload/2025/08/05/image.jpg)
  180. * @return 本地文件路径 (如: /www/wwwroot/server/uploadPath/upload/2025/08/05/image.jpg)
  181. */
  182. private static String convertWebPathToLocalPath(String webPath) {
  183. log.debug("转换Web路径到本地路径: {}", webPath);
  184. System.out.println("转换Web路径到本地路径: " + webPath);
  185. if (StringUtils.isEmpty(webPath)) {
  186. return null;
  187. }
  188. // 检查是否是有效的资源路径
  189. if (!webPath.startsWith(Constants.RESOURCE_PREFIX + "/")) {
  190. log.warn("不是有效的资源路径: {}", webPath);
  191. System.out.println("不是有效的资源路径: " + webPath);
  192. return null;
  193. }
  194. // 移除资源前缀,获取相对路径
  195. String relativePath = webPath.substring(Constants.RESOURCE_PREFIX.length() + 1);
  196. log.debug("相对路径: {}", relativePath);
  197. System.out.println("相对路径: " + relativePath);
  198. // 策略1: 使用配置的profile路径
  199. String profilePath = RuoYiConfig.getProfile();
  200. String localPath = Paths.get(profilePath, relativePath).toString();
  201. log.debug("策略1 - 使用profile路径: {} -> {}", profilePath, localPath);
  202. System.out.println("策略1 - 使用profile路径: " + profilePath + " -> " + localPath);
  203. // 检查文件是否存在
  204. File file = new File(localPath);
  205. if (file.exists()) {
  206. log.debug("策略1成功 - 文件存在: {}", localPath);
  207. System.out.println("策略1成功 - 文件存在: " + localPath);
  208. return localPath;
  209. } else {
  210. log.debug("策略1失败 - 文件不存在: {}", localPath);
  211. System.out.println("策略1失败 - 文件不存在: " + localPath);
  212. }
  213. return null;
  214. }
  215. /**
  216. * 将本地文件路径转换为Web访问路径
  217. *
  218. * @param localPath 本地文件路径
  219. * @return Web访问路径
  220. */
  221. private static String convertLocalPathToWebPath(String localPath) {
  222. // 步骤1:统一替换路径分隔符为正斜杠(兼容所有系统)
  223. if (StringUtils.isEmpty(localPath)) return null;
  224. String normalizedPath = localPath.replace("\\", "/"); // 关键点1:统一使用/
  225. log.debug("转换本地路径到Web路径: {}", normalizedPath);
  226. String profilePath = RuoYiConfig.getProfile();
  227. if (profilePath != null) {
  228. profilePath = profilePath.replace("\\", "/"); // 关键点2:配置路径也统一
  229. }
  230. // 步骤2:优化路径匹配逻辑(使用统一的分隔符)
  231. String webPath = null;
  232. // 策略1: 检查配置目录
  233. if (profilePath != null && normalizedPath.startsWith(profilePath)) {
  234. int startIndex = profilePath.endsWith("/") ?
  235. profilePath.length() :
  236. profilePath.length() + 1;
  237. String relativePath = normalizedPath.substring(startIndex);
  238. webPath = Constants.RESOURCE_PREFIX + "/" + relativePath;
  239. log.debug("策略1成功 - Web路径: {}", webPath);
  240. }
  241. // 策略2: 处理含upload的路径
  242. else if (normalizedPath.contains("/upload/")) {
  243. int uploadIndex = normalizedPath.indexOf("/upload/") + 1;
  244. webPath = Constants.RESOURCE_PREFIX + "/" + normalizedPath.substring(uploadIndex);
  245. log.debug("策略2成功 - Web路径: {}", webPath);
  246. }
  247. // 策略3: 兜底方案(文件名直用)
  248. else {
  249. int lastSlash = normalizedPath.lastIndexOf("/");
  250. String fileName = (lastSlash != -1) ?
  251. normalizedPath.substring(lastSlash + 1) :
  252. normalizedPath;
  253. webPath = Constants.RESOURCE_PREFIX + "/upload/" + fileName;
  254. log.debug("策略3成功 - Web路径: {}", webPath);
  255. }
  256. // 步骤3:确保结果有效性
  257. if (webPath != null) {
  258. log.info("转换成功: {} → {}", normalizedPath, webPath);
  259. return webPath;
  260. } else {
  261. log.error("转换失败: {}", normalizedPath);
  262. return null;
  263. }
  264. }
  265. /**
  266. * 使用Thumbnailator压缩图片
  267. *
  268. * @param inputPath 输入路径
  269. * @param outputPath 输出路径
  270. * @return 是否压缩成功
  271. */
  272. private static boolean compressImageWithThumbnailator(String inputPath, String outputPath) {
  273. log.info("使用Thumbnailator压缩图片: {} -> {}", inputPath, outputPath);
  274. System.out.println("使用Thumbnailator压缩图片: " + inputPath + " -> " + outputPath);
  275. try {
  276. // 确保输出目录存在
  277. File outputFile = new File(outputPath);
  278. File parentDir = outputFile.getParentFile();
  279. if (!parentDir.exists()) {
  280. log.debug("创建输出目录: {}", parentDir.getAbsolutePath());
  281. System.out.println("创建输出目录: " + parentDir.getAbsolutePath());
  282. parentDir.mkdirs();
  283. }
  284. // 使用二分法查找合适的压缩质量
  285. log.debug("查找最优压缩质量");
  286. System.out.println("查找最优压缩质量");
  287. float quality = findOptimalQuality(inputPath, outputPath);
  288. // 执行最终压缩
  289. log.debug("执行最终压缩,质量: {}", quality);
  290. System.out.println("执行最终压缩,质量: " + quality);
  291. Thumbnails.of(inputPath)
  292. .scale(1.0f) // 保持原尺寸
  293. .outputQuality(quality) // 设置压缩质量
  294. .toFile(outputPath);
  295. // 检查压缩后的文件大小
  296. File compressedFile = new File(outputPath);
  297. boolean success = compressedFile.exists() && compressedFile.length() <= TARGET_SIZE;
  298. log.info("压缩完成,文件存在: {}, 文件大小: {} 字节, 压缩成功: {}",
  299. compressedFile.exists(), compressedFile.length(), success);
  300. System.out.println("压缩完成,文件存在: " + compressedFile.exists() +
  301. ", 文件大小: " + compressedFile.length() + " 字节, 压缩成功: " + success);
  302. return success;
  303. } catch (IOException e) {
  304. log.error("压缩图片时发生IO异常: " + inputPath, e);
  305. System.err.println("压缩图片时发生IO异常: " + inputPath + ", 错误: " + e.getMessage());
  306. e.printStackTrace();
  307. return false;
  308. }
  309. }
  310. /**
  311. * 使用二分法查找最优压缩质量
  312. */
  313. private static float findOptimalQuality(String inputPath, String outputPath) {
  314. log.debug("使用二分法查找最优压缩质量: {}", inputPath);
  315. System.out.println("使用二分法查找最优压缩质量: " + inputPath);
  316. float minQuality = 0.1f;
  317. float maxQuality = 1.0f;
  318. float bestQuality = 0.8f;
  319. // 创建临时文件用于测试
  320. String tempPath = generateTempPath(outputPath);
  321. log.debug("创建临时文件用于测试: {}", tempPath);
  322. System.out.println("创建临时文件用于测试: " + tempPath);
  323. try {
  324. // 确保临时文件目录存在
  325. File tempFile = new File(tempPath);
  326. File parentDir = tempFile.getParentFile();
  327. if (!parentDir.exists()) {
  328. log.debug("创建临时文件目录: {}", parentDir.getAbsolutePath());
  329. System.out.println("创建临时文件目录: " + parentDir.getAbsolutePath());
  330. parentDir.mkdirs();
  331. }
  332. // 二分查找最优质量值
  333. for (int i = 0; i < 10; i++) { // 减少迭代次数,提高效率
  334. float testQuality = (minQuality + maxQuality) / 2;
  335. log.debug("第{}次测试,压缩质量: {}", i + 1, testQuality);
  336. System.out.println("第" + (i + 1) + "次测试,压缩质量: " + testQuality);
  337. try {
  338. // 确保临时文件不存在
  339. if (tempFile.exists()) {
  340. tempFile.delete();
  341. }
  342. // 测试当前质量的文件大小
  343. Thumbnails.of(inputPath)
  344. .scale(1.0f)
  345. .outputQuality(testQuality)
  346. .toFile(tempPath);
  347. // 等待文件写入完成
  348. Thread.sleep(100);
  349. long fileSize = tempFile.length();
  350. log.debug("测试结果 - 文件大小: {} 字节, 目标大小: {} 字节", fileSize, TARGET_SIZE);
  351. System.out.println("测试结果 - 文件大小: " + fileSize + " 字节, 目标大小: " + TARGET_SIZE + " 字节");
  352. if (fileSize <= TARGET_SIZE) {
  353. bestQuality = testQuality;
  354. minQuality = testQuality;
  355. log.debug("文件大小符合要求,调整最小质量为: {}", minQuality);
  356. System.out.println("文件大小符合要求,调整最小质量为: " + minQuality);
  357. } else {
  358. maxQuality = testQuality;
  359. log.debug("文件大小超过目标,调整最大质量为: {}", maxQuality);
  360. System.out.println("文件大小超过目标,调整最大质量为: " + maxQuality);
  361. }
  362. // 如果已经很接近目标大小,提前退出
  363. if (Math.abs(fileSize - TARGET_SIZE) < 10240) { // 10KB的容差
  364. bestQuality = testQuality;
  365. log.info("已接近目标大小,提前退出,最优质量: {}", bestQuality);
  366. System.out.println("已接近目标大小,提前退出,最优质量: " + bestQuality);
  367. break;
  368. }
  369. // 如果质量范围已经很小,提前退出
  370. if (Math.abs(maxQuality - minQuality) < 0.05f) {
  371. log.info("质量范围已经很小,提前退出,最优质量: {}", bestQuality);
  372. System.out.println("质量范围已经很小,提前退出,最优质量: " + bestQuality);
  373. break;
  374. }
  375. } catch (IOException e) {
  376. log.warn("测试压缩质量 {} 时出现异常: {}", testQuality, e.getMessage());
  377. System.out.println("测试压缩质量 " + testQuality + " 时出现异常: " + e.getMessage());
  378. // 如果当前质量测试失败,调整范围继续测试
  379. maxQuality = testQuality;
  380. continue;
  381. } catch (InterruptedException e) {
  382. log.warn("等待文件写入时被中断");
  383. System.out.println("等待文件写入时被中断");
  384. Thread.currentThread().interrupt();
  385. break;
  386. }
  387. // 删除临时文件
  388. if (tempFile.exists()) {
  389. tempFile.delete();
  390. }
  391. }
  392. } catch (Exception e) {
  393. log.error("查找最优压缩质量时发生异常", e);
  394. System.err.println("查找最优压缩质量时发生异常: " + e.getMessage());
  395. e.printStackTrace();
  396. // 如果出错,使用默认质量
  397. bestQuality = 0.6f;
  398. } finally {
  399. // 清理可能残留的临时文件
  400. File tempFile = new File(tempPath);
  401. if (tempFile.exists()) {
  402. log.debug("清理残留临时文件: {}", tempPath);
  403. System.out.println("清理残留临时文件: " + tempPath);
  404. tempFile.delete();
  405. }
  406. }
  407. log.info("最优压缩质量查找完成: {}", bestQuality);
  408. System.out.println("最优压缩质量查找完成: " + bestQuality);
  409. return bestQuality;
  410. }
  411. /**
  412. * 生成临时文件路径,保持正确的图片扩展名
  413. *
  414. * @param outputPath 输出文件路径
  415. * @return 临时文件路径
  416. */
  417. private static String generateTempPath(String outputPath) {
  418. File outputFile = new File(outputPath);
  419. String fileName = outputFile.getName();
  420. String parentDir = outputFile.getParent();
  421. int dotIndex = fileName.lastIndexOf('.');
  422. if (dotIndex == -1) {
  423. // 没有扩展名,默认添加.jpg
  424. return Paths.get(parentDir, fileName + "_comp.jpg").toString();
  425. } else {
  426. String nameWithoutExt = fileName.substring(0, dotIndex);
  427. String extension = fileName.substring(dotIndex);
  428. return Paths.get(parentDir, nameWithoutExt + "_comp" + extension).toString();
  429. }
  430. }
  431. /**
  432. * 生成压缩后的本地文件路径(在同一目录下)
  433. *
  434. * @param originalPath 原文件路径
  435. * @return 压缩后的文件路径
  436. */
  437. private static String generateCompressedLocalPath(String originalPath) {
  438. log.debug("生成压缩后本地文件路径: {}", originalPath);
  439. System.out.println("生成压缩后本地文件路径: " + originalPath);
  440. File originalFile = new File(originalPath);
  441. String parentDir = originalFile.getParent();
  442. String fileName = originalFile.getName();
  443. int dotIndex = fileName.lastIndexOf('.');
  444. String compressedPath;
  445. if (dotIndex == -1) {
  446. compressedPath = Paths.get(parentDir, fileName + "_comp.jpg").toString();
  447. } else {
  448. String nameWithoutExt = fileName.substring(0, dotIndex);
  449. String extension = fileName.substring(dotIndex);
  450. // 对于PNG文件,转换为JPG以获得更好的压缩效果
  451. if (".png".equalsIgnoreCase(extension)) {
  452. extension = ".jpg";
  453. }
  454. String compressedFileName = nameWithoutExt + "_comp" + extension;
  455. compressedPath = Paths.get(parentDir, compressedFileName).toString();
  456. }
  457. log.debug("生成的压缩文件路径: {}", compressedPath);
  458. System.out.println("生成的压缩文件路径: " + compressedPath);
  459. return compressedPath;
  460. }
  461. /**
  462. * 批量压缩图片(Web路径)
  463. *
  464. * @param webPaths Web访问路径数组
  465. * @return 压缩后的Web访问路径数组
  466. */
  467. public static String[] compressImagesByWebPath(String[] webPaths) {
  468. log.info("批量压缩图片,数量: {}", webPaths != null ? webPaths.length : 0);
  469. System.out.println("批量压缩图片,数量: " + (webPaths != null ? webPaths.length : 0));
  470. if (webPaths == null) {
  471. log.warn("Web路径数组为空");
  472. System.out.println("Web路径数组为空");
  473. return null;
  474. }
  475. String[] compressedPaths = new String[webPaths.length];
  476. for (int i = 0; i < webPaths.length; i++) {
  477. log.debug("批量压缩第{}张图片: {}", i + 1, webPaths[i]);
  478. System.out.println("批量压缩第" + (i + 1) + "张图片: " + webPaths[i]);
  479. compressedPaths[i] = compressImageByWebPath(webPaths[i]);
  480. }
  481. log.info("批量压缩完成");
  482. System.out.println("批量压缩完成");
  483. return compressedPaths;
  484. }
  485. /**
  486. * 检查路径是否为若依资源路径
  487. *
  488. * @param path 路径
  489. * @return 是否为资源路径
  490. */
  491. public static boolean isResourcePath(String path) {
  492. boolean result = StringUtils.isNotEmpty(path) && path.startsWith(Constants.RESOURCE_PREFIX + "/");
  493. log.debug("检查是否为资源路径: {} -> {}", path, result);
  494. System.out.println("检查是否为资源路径: " + path + " -> " + result);
  495. return result;
  496. }
  497. /**
  498. * 获取文件大小(字节)
  499. *
  500. * @param webPath Web访问路径
  501. * @return 文件大小,如果文件不存在返回-1
  502. */
  503. public static long getFileSize(String webPath) {
  504. log.debug("获取文件大小: {}", webPath);
  505. System.out.println("获取文件大小: " + webPath);
  506. String localPath = convertWebPathToLocalPath(webPath);
  507. if (StringUtils.isEmpty(localPath)) {
  508. log.warn("无法转换Web路径到本地路径");
  509. System.out.println("无法转换Web路径到本地路径");
  510. return -1;
  511. }
  512. File file = new File(localPath);
  513. long fileSize = file.exists() ? file.length() : -1;
  514. log.debug("文件大小: {} 字节", fileSize);
  515. System.out.println("文件大小: " + fileSize + " 字节");
  516. return fileSize;
  517. }
  518. }