- Jun 19 Wed 2024 00:49
使用 MapStruct 快速進行物件的轉換
- Mar 19 Tue 2024 20:24
Java - 解壓縮 (unzip),並寫一個單元測試進行測試
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lombok.extern.slf4j.Slf4j; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.nio.charset.Charset; | |
import java.nio.charset.StandardCharsets; | |
import java.nio.file.Path; | |
import java.util.zip.ZipEntry; | |
import java.util.zip.ZipInputStream; | |
@Slf4j | |
public final class ZipUtils { | |
private ZipUtils() {} | |
public static void unzip(Path inputZipFile, Path outputDirectory) throws IOException { | |
File destDir = new File(outputDirectory.toString()); | |
try { | |
// 先試試 utf8 | |
unzip(inputZipFile, destDir, StandardCharsets.UTF_8); | |
} catch (RuntimeException e) { | |
log.error("UTF_8解壓縮失敗"); | |
// 再試試看 big5 | |
unzip(inputZipFile, destDir, Charset.forName("Big5")); | |
} | |
} | |
private static void unzip(Path inputZipFile, File destDir, Charset charset) throws IOException { | |
log.info("開始使用 Charset: {} 進行解壓縮", charset); | |
byte[] buffer = new byte[1024]; | |
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(inputZipFile.toFile()), charset)) { | |
ZipEntry zipEntry = zis.getNextEntry(); | |
while (zipEntry != null) { | |
File newFile = newFile(destDir, zipEntry); | |
if (zipEntry.isDirectory()) { | |
if (!newFile.isDirectory() && !newFile.mkdirs()) { | |
throw new IOException("Failed to create directory " + newFile); | |
} | |
} else { | |
File parent = newFile.getParentFile(); | |
if (!parent.isDirectory() && !parent.mkdirs()) { | |
throw new IOException("Failed to create directory " + parent); | |
} | |
writeFileContent(zis, newFile, buffer); | |
} | |
zipEntry = zis.getNextEntry(); | |
} | |
} | |
} | |
private static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException { | |
File destFile = new File(destinationDir, zipEntry.getName()); | |
String destDirPath = destinationDir.getCanonicalPath(); | |
String destFilePath = destFile.getCanonicalPath(); | |
if (!destFilePath.startsWith(destDirPath + File.separator)) { | |
throw new IOException("Entry is outside of the target dir: " + zipEntry.getName()); | |
} | |
return destFile; | |
} | |
private static void writeFileContent(ZipInputStream zis, File newFile, byte[] buffer) throws IOException { | |
// write file content | |
try (FileOutputStream fos = new FileOutputStream(newFile)) { | |
int len; | |
while ((len = zis.read(buffer)) > 0) { | |
fos.write(buffer, 0, len); | |
} | |
} | |
} | |
} |
接著我們寫一個單元測試來測試一下功能是否正確
- Oct 05 Thu 2023 16:19
Java - 只給起訖年月時間(yyyy/MM),如何判斷是否在有效時間內
需求為當我們只有開始與結束的年月時間,時間格式為yyyy/MM,例如 2023/09 ~ 2023/12
我們想要知道這個起訖時間是否為有限時間,意思是說開始時間是否已經生效,是不是已經超過結束時間 (過期)
- Aug 19 Sat 2023 23:18
Spring Security 授權與認證
這篇文章會介紹如從零開始一步一步透過使用 Spring Security 來實作登入、認證、角色權限等機制
所有程式碼可以到我的 GitHub 查看: https://github.com/lakesd6531/springsecurity
- Jul 03 Mon 2023 17:35
SpringBoot3 + Swagger
- Jun 01 Thu 2023 11:31
在 Spring Boot 當中加入 Swagger
- Apr 07 Fri 2023 09:43
Spring Boot Validation - 如何使用Spring Boot自動驗證參數正確性
- Mar 24 Fri 2023 11:44
如何使用SQL取代欄位每一筆資料的部分內容
- Mar 21 Tue 2023 22:14
如何消磁淨化水晶
水晶礦石從開採、到加工、到販售,這過程中不知道經歷過多少人的手,所以拿到水晶時建議把水晶進行消磁淨化一下。
此外,你可以把你的水晶、天珠、瑪瑙、或是木藝品,想像成是一顆電池,隨著你的配戴,它的電量會慢慢耗盡
- Mar 21 Tue 2023 11:28
為什麼Spring不推薦使用@Autowired進行依賴注入 (Dependency injection)