使用 ProcessBuilder 的问题
Issues Using ProcessBuilder
我在使用 ProcessBuilder.start();
时遇到一些问题。
下面是代码的示例:
List<String> listOfStrings = new ArrayList<String>();
myListOfString.add("zip");
myListOfString.add("-r");
myListOfString.add(destinationPath);
myListOfString.add(newFilePath);
File zipFile = new File(workingDirectory, fileName + ".zip");
ProcessBuilder processBuilder = new ProcessBuilder(listOfStrings);
prcoessBuilder.directory(workingDirectory);
try{
Process p = processBuilder.start();
...
...
...
workingDirectory
已使用 workingDirectory.isDirectory()
.
验证为工作目录
问题发生在 Process p = processBuilder.start();
,它抛出 IOException。
下面是堆栈跟踪:
java.io.IOException: Cannot run program "zip" (in directory "<Path to workingDirectory>"): error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
...
...
...
workingDirectory
不指向特定文件(例如:/path/to/
,而不是 /path/to/file.zip
),但是,它是一个有效的目录。这可能是问题所在吗?
由于项目的性质,我无法给出确切的代码,但我无法想象如果它在 Process p = processBuilder.start();
时崩溃,输入会不会有太大影响,然而,这就是我伸出援手的原因所以可能是这样。
如果需要任何说明,请告诉我。
错误信息说Java在当前目录或路径上没有找到名为zip
的可执行文件,可以看到:
String systemPath = System.getenv("PATH");
System.out.println("PATH="+systemPath);
修复您的启动器以包含“zip”的完整路径或修复用于您的 Java VM 的路径以包含包含 zip
.
的目录
myListOfString.add("/the/path/to/zip");
或类似的东西(取决于您的 shell / 终端)
export PATH=/the/path/to:$PATH
正如@Abra 所建议的,有更好的方法可以在 Java 内压缩而不依赖 ProcessBuilder,例如:
public static void zip(Path dir, Path zip) throws IOException
{
Map<String, String> env = Map.of("create", "true");
try (FileSystem fs = FileSystems.newFileSystem(zip, env))
{
// This predicate processed the action because it makes use of BasicFileAttributes
// Rather than process a forEach stream which has to call Files.isDirectory(path)
BiPredicate<Path, BasicFileAttributes> foreach = (p,a) -> {
copy(p,a, fs.getPath("/"+dir.relativize(p)));
return false;
};
Files.find(dir, Integer.MAX_VALUE, foreach).count();
}
System.out.println("ZIPPED "+dir +" to "+zip);
}
private static void copy(Path from, BasicFileAttributes a, Path target)
{
System.out.println("Copy "+(a.isDirectory() ? "DIR " : "FILE")+" => "+target);
try
{
if (a.isDirectory())
Files.createDirectories(target);
else if (a.isRegularFile())
Files.copy(from, target, StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e)
{
throw new UncheckedIOException(e);
}
}
我在使用 ProcessBuilder.start();
时遇到一些问题。
下面是代码的示例:
List<String> listOfStrings = new ArrayList<String>();
myListOfString.add("zip");
myListOfString.add("-r");
myListOfString.add(destinationPath);
myListOfString.add(newFilePath);
File zipFile = new File(workingDirectory, fileName + ".zip");
ProcessBuilder processBuilder = new ProcessBuilder(listOfStrings);
prcoessBuilder.directory(workingDirectory);
try{
Process p = processBuilder.start();
...
...
...
workingDirectory
已使用 workingDirectory.isDirectory()
.
问题发生在 Process p = processBuilder.start();
,它抛出 IOException。
下面是堆栈跟踪:
java.io.IOException: Cannot run program "zip" (in directory "<Path to workingDirectory>"): error=2, No such file or directory
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
...
...
...
workingDirectory
不指向特定文件(例如:/path/to/
,而不是 /path/to/file.zip
),但是,它是一个有效的目录。这可能是问题所在吗?
由于项目的性质,我无法给出确切的代码,但我无法想象如果它在 Process p = processBuilder.start();
时崩溃,输入会不会有太大影响,然而,这就是我伸出援手的原因所以可能是这样。
如果需要任何说明,请告诉我。
错误信息说Java在当前目录或路径上没有找到名为zip
的可执行文件,可以看到:
String systemPath = System.getenv("PATH");
System.out.println("PATH="+systemPath);
修复您的启动器以包含“zip”的完整路径或修复用于您的 Java VM 的路径以包含包含 zip
.
myListOfString.add("/the/path/to/zip");
或类似的东西(取决于您的 shell / 终端)
export PATH=/the/path/to:$PATH
正如@Abra 所建议的,有更好的方法可以在 Java 内压缩而不依赖 ProcessBuilder,例如:
public static void zip(Path dir, Path zip) throws IOException
{
Map<String, String> env = Map.of("create", "true");
try (FileSystem fs = FileSystems.newFileSystem(zip, env))
{
// This predicate processed the action because it makes use of BasicFileAttributes
// Rather than process a forEach stream which has to call Files.isDirectory(path)
BiPredicate<Path, BasicFileAttributes> foreach = (p,a) -> {
copy(p,a, fs.getPath("/"+dir.relativize(p)));
return false;
};
Files.find(dir, Integer.MAX_VALUE, foreach).count();
}
System.out.println("ZIPPED "+dir +" to "+zip);
}
private static void copy(Path from, BasicFileAttributes a, Path target)
{
System.out.println("Copy "+(a.isDirectory() ? "DIR " : "FILE")+" => "+target);
try
{
if (a.isDirectory())
Files.createDirectories(target);
else if (a.isRegularFile())
Files.copy(from, target, StandardCopyOption.REPLACE_EXISTING);
}
catch (IOException e)
{
throw new UncheckedIOException(e);
}
}