可以在运行java时修改工作目录吗

  介绍

可以在运行java时修改工作目录吗?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

<强>前言

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

程序启动目录即工作目录是/用户/qkkcoolmax/work-private testuserdir/呵呵

public  static  void  main (String [], args), {   File 才能;File =, new 文件(“哈哈/test.log");   System.out.println才能(file.getAbsolutePath ());//用户/才能qkkcoolmax/work-private/testuserdir/呵呵/哈哈/test.log   System.out.println才能(System.setProperty (“user.dir",,“/用户/qkkcoolmax/work-private/testuserdir"));//用户/qkkcoolmax/才能work-private/testuserdir/呵呵   System.out.println才能(System.getProperty (“user.dir"));//用户/才能qkkcoolmax/work-private/testuserdir   System.out.println才能(file.getAbsolutePath ());//用户/才能qkkcoolmax/work-private testuserdir/哈哈/test.log   try {才能   ,,new  FileOutputStream(文件);   ,,},catch  (FileNotFoundException  e), {   ,,e.printStackTrace ();   ,,}   以前,}

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

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

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

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

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

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

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

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

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

<强>引入依赖

& lt; dependency>   ,& lt; groupId> com.github.jnr   ,& lt; artifactId> jnr-posix   ,& lt; version> 3.0.47   & lt;/dependency>

<强>使用示例

public  class  Main  {      ,private  static  POSIX  posix;      ,public  static  void  main (String [], args), {   posix 才能=,POSIXFactory.getPOSIX (new  DummyPOSIXHandler(),,真的);   File 才能;File =, new 文件(“哈哈/test.log");   System.out.println才能(file.getAbsolutePath ());//用户/才能qkkcoolmax/work-private/testuserdir/呵呵/哈哈/test.log   System.out.println才能(System.setProperty (“user.dir",,“/用户/qkkcoolmax/work-private/testuserdir"));   posix.chdir才能(System.getProperty (“user.dir"));//用户/qkkcoolmax/才能work-private/testuserdir/呵呵   System.out.println才能(System.getProperty (“user.dir"));//用户/才能qkkcoolmax/work-private/testuserdir   System.out.println才能(file.getAbsolutePath ());//用户/才能qkkcoolmax/work-private testuserdir/哈哈/test.log   try {才能   ,,new  FileOutputStream(文件);   ,,},catch  (FileNotFoundException  e), {   ,,e.printStackTrace ();   ,,}   ,}   }

可以在运行java时修改工作目录吗