可以在运行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时处理各种跨平台的逻辑。
引入依赖
<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起来,能够成功创建出 /Users/qkkcoolmax/work-private/testuserdir/haha/test.log文件,无任何异常。
Java的特点有哪些 1.Java语言作为静态面向对象编程语言的代表,实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。 2.Java具有简单性、面向对象、分布式、安全性、平台独立与可移植性、动态性等特点。 3.使用Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
关于可以在运行java时修改工作目录吗问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。