Springboot 複製jar包中的檔案
在spring專案中,如果以war包的方式執行在tomcat中,在執行前會把war包解壓到webapps目錄下,resource下的檔案也會以普通檔案的形式存在,如果有一些特殊檔案需要讀取/執行/使用,則以正常的file形式讀取就可以。 但springboot以jar包方式執行,若是想獲取resource下的某些靜態檔案,有以下幾種方式:
- 1.resourceload的方式讀取
- 2.unzip解壓部分jar包中的檔案
- 3.jar 命令解壓整個jar包
第一種方式可以獲取一些靜態資源的內容,以io流的方式讀取並使用,但是不能執行,例如resource下有一個adb,則需要用流的方式複製到檔案系統內,才能繼續執行。如果這樣的檔案較多且目錄比較複雜,還需要遞迴複製。
第二種方式在windows與linux中不相容,均需要依賴相關的unzip工具
第三種方式只需要jre,比較通用,但會解壓整個jar包。
本文主要介紹第三種方式。
jar命令介紹
jar命令引數:
jar命令格式:jar {c t x u f }[ v m e 0 M i ][-C 目錄]檔名...
其中{ctxu}這四個引數必須選選其一。[v f m e 0 M i ]是可選引數,檔名也是必須的。
引數 | 作用 |
---|---|
-c | 建立一個jar包 |
-t | 顯示jar中的內容列表 |
-x | 解壓jar包 |
-u | 新增檔案到jar包中 |
-f | 指定jar包的檔名 |
-v | 生成詳細的報造,並輸出至標準裝置 |
-m | 指定manifest.mf檔案.(manifest.mf檔案中可以對jar包及其中的內容作一些一設定) |
-0 | 產生jar包時不對其中的內容進行壓縮處理 |
-M | 不產生所有檔案的清單檔案(Manifest.mf)。這個引數與忽略掉-m引數的設定 |
-i | 為指定的jar檔案建立索引檔案 |
-C | 表示轉到相應的目錄下執行jar命令,相當於cd到那個目錄,然後不帶-C執行jar命令 |
- jar -cvf hello.jar hello
建立並顯示打包過程 - jar -xvf hello.jar
解壓jar包並顯示過程
我們需要用到的就是jar -xf命令
在springboot中解壓jar包,並獲取jar包中的resource的目錄
先上程式碼:
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
@Slf4j
public class PathUtil {
private static final String SPEA = java.io.File.separator;
/**
* 除錯時輸出:D:\workspace\copyfilesfromjar
* windows jar包輸出: D:\workspace\copyfilesfromjar\target
* linux jar包輸出:/home/dongweihang
*
* @return 返回jar執行目錄
*/
public static String getApplicationClassPath() {
return System.getProperty("user.dir");
}
/**
* @return 返回resources目錄(需要提前把jar包中的檔案解壓到系統目錄中)
*/
public static String getResourcePath() {
File file = new File(getApplicationClassPath());
if (file.exists() && file.isDirectory() && file.listFiles() != null) {
String jarFileName = Arrays.stream(file.listFiles()).map(File::getName).filter(s -> s.contains(".jar")).findFirst().orElse(null);
String resourcePath = null;
if (jarFileName != null) {
//如果目錄下包含jar ,說明是用jar包執行的,先用jar -xf解壓
try {
Process process = Runtime.getRuntime().exec("jar -xf " + jarFileName);
process.waitFor();
} catch (IOException | InterruptedException e) {
log.info("can not exec jar -xf");
e.printStackTrace();
return null;
}
resourcePath = file.getAbsolutePath().concat(SPEA).concat("BOOT-INF").concat(SPEA).concat("classes").concat(SPEA);
return resourcePath;
} else {
//不包含jar,說明在除錯模式中 後接\target\classes
resourcePath = file.getAbsolutePath().concat(SPEA).concat("target").concat(SPEA).concat("classes").concat(SPEA);
return resourcePath;
}
}
return null;
}
}
複製程式碼
首先通過System.getProperty("user.dir")獲取到jar包的執行目錄,這裡要注意在除錯時不會用jar包執行,因此目錄下不存在jar,相應的resource檔案也已經在target/classes下,以普通檔案存在。因此這種情況不需要解壓jar包。
那麼只要是以jar包形式執行,通過Runtime.getRuntime().exec("jar -xf " + jarFileName)解壓jar包之後,相應的檔案會存在在/BOOT-INF/classes下。
例如我將需要使用的檔案放在resource下的file目錄下
在解壓後會在解壓後我們操作這些檔案就可以按照file 的方式來操作了。