java在運(yùn)行時(shí)能修改工作目錄嗎
前言
首先我們直接來(lái)看一個(gè)例子:
程序啟動(dòng)目錄即工作目錄是/Users/qkkcoolmax/work-private/testuserdir/hehe
public static void main(String[] args) { File file = new File("haha/test.log"); System.out.println(file.getAbsolutePath()); //Users/qkkcoolmax/work-private/testuserdir/hehe/haha/test.log System.out.println(System.setProperty("user.dir", "/Users/qkkcoolmax/work-private/testuserdir")); //Users/qkkcoolmax/work-private/testuserdir/hehe System.out.println(System.getProperty("user.dir")); //Users/qkkcoolmax/work-private/testuserdir System.out.println(file.getAbsolutePath()); //Users/qkkcoolmax/work-private/testuserdir/haha/test.log try { new FileOutputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } }
該程序會(huì)拋FileNotFoundException異常。這是由于File對(duì)象使用了相對(duì)路徑創(chuàng)建,雖然我們動(dòng)態(tài)修改了System.proproties中的user.dir即修改了java層面的工作目錄,但并沒有修改到j(luò)vm中實(shí)際記錄的工作目錄,所以需要?jiǎng)?chuàng)建的文件路徑中hehe/haha目錄并不存在,從而拋異常。其實(shí)System.property只是修改了System中的一個(gè)靜態(tài)map變量。
而getAbsolutePath返回的是修改工作目錄后的文件路徑,這是由于getAbsolutePath中總是會(huì)用System.getProperty("user.dir")
來(lái)和相對(duì)路徑拼接,得到absolutePath。
綜上,我們了解到System.setProperty("user.dir",newPath)
的方式是無(wú)法修改進(jìn)程實(shí)際的工作目錄的,這個(gè)值是存放在jvm底層數(shù)據(jù)結(jié)構(gòu)中。但是有些特殊場(chǎng)景,我們確實(shí)希望能動(dòng)態(tài)修改一下工作目錄。譬如一個(gè)服務(wù)端進(jìn)程需要處理不同目錄下的文件,歷史代碼或者框架中使用了一些相對(duì)路徑,我們難以替換成絕對(duì)路徑時(shí),動(dòng)態(tài)修改工作目錄就成了唯一實(shí)現(xiàn)目標(biāo)的途徑。
所以,java是否可以動(dòng)態(tài)修改工作目錄呢? 先說結(jié)論,是可以的!
首先,java語(yǔ)言層面并沒有提供這樣的接口。
其次,我們知道在c語(yǔ)言中,可以很方便的調(diào)用chdir系統(tǒng)調(diào)用來(lái)切換當(dāng)前進(jìn)程的工作目錄。那么只要java能調(diào)用到j(luò)vm中鏈進(jìn)來(lái)的libc中的chdir不就好了么。
java調(diào)c有幾種方式呢?有一定經(jīng)驗(yàn)的讀者可能馬上會(huì)想到JNI。實(shí)際上,我們可以采用更好的方式即JNA。JNA(Java Native Access )提供一組Java工具類用于在運(yùn)行期間動(dòng)態(tài)訪問系統(tǒng)本地庫(kù)(native library:如Window的dll)而不需要編寫任何Native/JNI代碼。
簡(jiǎn)單來(lái)說,JNA可以讓java代碼直接調(diào)用c代碼(包括jvm里面的代碼),使用方式相比jni更加簡(jiǎn)單方便。
對(duì)JNA的介紹網(wǎng)上資料還蠻豐富的,感興趣的讀者可以自行搜索研究。這里我們直接使用了jnr-posixz(https://github.com/jnr/jnr-posixz)。該庫(kù)已經(jīng)對(duì)不同平臺(tái)的JNA調(diào)用實(shí)現(xiàn)了良好的封裝,避免我們使用原生的JNA時(shí)處理各種跨平臺(tái)的邏輯。
引入依賴
<dependency> <groupId>com.github.jnr</groupId> <artifactId>jnr-posix</artifactId> <version>3.0.47</version> </dependency>
使用示例
public class Main { private static POSIX posix; public static void main(String[] args) { posix = POSIXFactory.getPOSIX(new DummyPOSIXHandler(), true); File file = new File("haha/test.log"); System.out.println(file.getAbsolutePath()); //Users/qkkcoolmax/work-private/testuserdir/hehe/haha/test.log System.out.println(System.setProperty("user.dir", "/Users/qkkcoolmax/work-private/testuserdir")); posix.chdir(System.getProperty("user.dir")); //Users/qkkcoolmax/work-private/testuserdir/hehe System.out.println(System.getProperty("user.dir")); //Users/qkkcoolmax/work-private/testuserdir System.out.println(file.getAbsolutePath()); //Users/qkkcoolmax/work-private/testuserdir/haha/test.log try { new FileOutputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } } }
run起來(lái),能夠成功創(chuàng)建出 /Users/qkkcoolmax/work-private/testuserdir/haha/test.log文件,無(wú)任何異常。
好了,動(dòng)態(tài)修改java工作目錄達(dá)成,請(qǐng)自行取用。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
- java怎么創(chuàng)建目錄(刪除/修改/復(fù)制目錄及文件)代碼實(shí)例
- java讀取resource目錄下文件的方法示例
- Java如何在不存在文件夾的目錄下創(chuàng)建文件
- Java實(shí)現(xiàn)讀取文件夾下(包括子目錄)所有文件的文件名
- Java實(shí)現(xiàn)上傳文件圖片到指定服務(wù)器目錄
- Java實(shí)現(xiàn)文件或文件夾的復(fù)制到指定目錄實(shí)例
- java 用遞歸獲取一個(gè)目錄下的所有文件路徑的小例子
- java對(duì)指定目錄下文件讀寫操作介紹
- Java遞歸 遍歷目錄的小例子
- Java文件操作之按行讀取文件和遍歷目錄的方法
相關(guān)文章
SpringMVC中RequestParam注解的簡(jiǎn)單理解
@RequestMapping RequestMapping是一個(gè)用來(lái)處理請(qǐng)求地址映射的注解,可用于類或方法上,下面這篇文章主要給大家介紹了關(guān)于SpringMVC中RequestParam注解的簡(jiǎn)單理解,需要的朋友可以參考下2022-03-03maven導(dǎo)入本地倉(cāng)庫(kù)jar包,報(bào):Could?not?find?artifact的解決
這篇文章主要介紹了maven導(dǎo)入本地倉(cāng)庫(kù)jar包,報(bào):Could?not?find?artifact的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03java數(shù)字和中文算數(shù)驗(yàn)證碼的實(shí)現(xiàn)
這篇文章主要介紹了java數(shù)字和中文算數(shù)驗(yàn)證碼的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07關(guān)于Spring中Bean的創(chuàng)建進(jìn)行更多方面的控制
今天小編就為大家分享一篇關(guān)于關(guān)于Spring中Bean的創(chuàng)建進(jìn)行更多方面的控制,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01基于Java實(shí)現(xiàn)考試管理系統(tǒng)
這篇文章主要介紹了基于Java實(shí)現(xiàn)的考試管理系統(tǒng),項(xiàng)目運(yùn)用到的技術(shù)有Springboot、Maven、Jpa、Vue等等,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2021-12-12Fluent Mybatis實(shí)現(xiàn)環(huán)境隔離和租戶隔離
我們?cè)趯?shí)際的業(yè)務(wù)開發(fā)中,經(jīng)常會(huì)碰到環(huán)境邏輯隔離和租戶數(shù)據(jù)邏輯隔離的問題。本文就詳細(xì)的來(lái)介紹一下,感興趣的小伙伴們可以參考一下2021-08-08