Java中实现cd命令:运⾏中更改当前⼯作⽬录
因为⼀些原因,想在Java中模拟部分Shell命令的功能,⽐如cd、pwd、ls等。
实现pwd很简单,返回Property("user.dir")即可;
实现ls也不难,⽤java.nio.file.Files::walk还能实现递归遍历⽬录;
但在纯Java中实现cd——动态的切换当前⼯作⽬录——似乎不是那么容易。
调⽤System.setProperty("user.dir", "xxx")修改user.dir后,能影响java.io.File和java.nio.file.Path的后续创建,但不会影
响java.io.FileOutputStream、java.lang.Process等,即写⼊⽂件、⼦进程等当前⽬录还是进程启动时的⽬录,不会随系统属性的修改⽽修改。例如:
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Application {
public static void main(String[] args) throws Exception {
System.out.println(new File(".").getCanonicalPath());
String home = Property("user.home");
String target = at("/Desktop");
System.setProperty("user.dir", target);
System.out.println(new File(".").getCanonicalPath());
try (OutputStream fout = new FileOutputStream("a.txt")) {
fout.write("hello world".getBytes());
}
}
}
在任何⾮桌⾯⽬录下执⾏上述代码,第⼀⾏输出当前路径,第⼆⾏输出桌⾯路径,但a.txt不是创建在桌⾯。
经过Google,在上到了⼀个解决⽅案:通过jna-posix修改当前⽬录。不过原始答案中的⽅法有些过时,经过折腾,到了在Mac下⾏之有效的⽅法。细节如下。
⼀、l 引⼊依赖包
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>com.github.jnr</groupId>
<artifactId>jnr-posix</artifactId>
<version>3.0.46</version>
</dependency>
⼆、实现POSIXHandler
stants.platform.Errno;
import jnr.posix.POSIXHandler;
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PrintStream;
import java.util.Map;
import static java.util.List;
public class PosixHandler implements POSIXHandler {
@Override
public void error(Errno error, String extraData) {
}
@Override
public void error(Errno error, String methodName, String extraData) {        printf("%s %s %s\n", error, methodName, extraData);    }
@Override
public void unimplementedError(String methodName) {
}
@Override
public void warn(WARNING_ID id, String message, data) {        printf("%s %s %s\n", id, message, data);
}
@Override
public boolean isVerbose() {
return false;
}
@Override
public File getCurrentWorkingDirectory() {
return new Property("user.dir"));
}
@Overridejava stream
public String[] getEnv() {
v()
.entrySet()
.stream()
.map(Map.Entry::toString)
.collect(toList())
.toArray(new String[0]);
}
@Override
public InputStream getInputStream() {
return System.in;
}
@Override
public PrintStream getOutputStream() {
return System.out;
}
@Override
public int getPID() {
return 0;
}
@Override
public PrintStream getErrorStream() {
;
}
}
三、利⽤Posix对象修改当前路径
import jnr.posix.POSIX;
import jnr.posix.POSIXFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
public class Application {
public static void main(String[] args) throws Exception {
System.out.println(new File(".").getCanonicalPath());
String home = Property("user.home");
String target = at("/Desktop");
System.setProperty("user.dir", target);
POSIX posix = POSIX(new PosixHandler(), true);        posix.chdir(target);
System.out.println(new File(".").getCanonicalPath());
try (OutputStream fout = new FileOutputStream("a.txt")) {
fout.write("hello world".getBytes());
}
}
}
此时,再运⾏该程序,a.txt会被创建在桌⾯⽬录下。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。