java 设置工作目录下_java在运行时能修改工作目录吗

前言

首先我们直接来看一个例子:

程序启动目录即工作目录是/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();

}

}

该程序会抛FileNotFoundException异常。这是由于File对象使用了相对路径创建,虽然我们动态修改了System.proproties中的user.dir即修改了java层面的工作目录,但并没有修改到jvm中实际记录的工作目录,所以需要创建的文件路径中hehe/haha目录并不存在,从而抛异常。其实System.property只是修改了System中的一个静态map变量。

而getAbsolutePath返回的是修改工作目录后的文件路径,这是由于getAbsolutePath中总是会用System.getProperty("user.dir")来和相对路径拼接,得到absolutePath。

综上,我们了解到System.setProperty("user.dir",newPath)的方式是无法修改进程实际的工作目录的,这个值是存放在jvm底层数据结构中。但是有些特殊场景,我们确实希望能动态修改一下工作目录。譬如一个服务端进程需要处理不同目录下的文件,历史代码或者框架中使用了一些相对路径,我们难以替换成绝对路径时,动态修改工作目录就成了唯一实现目标的途径。

所以,java是否可以动态修改工作目录呢? 先说结论,是可以的!

首先,java语言层面并没有提供这样的接口。

其次,我们知道在c语言中,可以很方便的调用chdir系统调用来切换当前进程的工作目录。那么只要java能调用到jvm中链进来的libc中的chdir不就好了么。

java调c有几种方式呢?有一定经验的读者可能马上会想到JNI。实际上,我们可以采用更好的方式即JNA。JNA(Java Native Access )提供一组Java工具类用于在运行期间动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。

简单来说,JNA可以让java代码直接调用c代码(包括jvm里面的代码),使用方式相比jni更加简单方便。

对JNA的介绍网上资料还蛮丰富的,感兴趣的读者可以自行搜索研究。这里我们直接使用了jnr-posixz(https://github.com/jnr/jnr-posixz)。该库已经对不同平台的JNA调用实现了良好的封装,避免我们使用原生的JNA时处理各种跨平台的逻辑。

引入依赖

com.github.jnr

jnr-posix

3.0.47

使用示例

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起来,能够成功创建出 /Users/qkkcoolmax/work-private/testuserdir/haha/test.log文件,无任何异常。

好了,动态修改java工作目录达成,请自行取用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值