Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在java中使用ProcessBuilder提取7zip cmd_Java_Cmd_Extract_Processbuilder_7zip - Fatal编程技术网

在java中使用ProcessBuilder提取7zip cmd

在java中使用ProcessBuilder提取7zip cmd,java,cmd,extract,processbuilder,7zip,Java,Cmd,Extract,Processbuilder,7zip,使用Java 10 ProcessBuilder和带有命令行的7z.exe(18.05)将归档文件提取到所需类别时遇到问题。当我使用Windows CMD时,该命令与预期的完全相同,但当我的JavaFX应用程序使用ProcessBuilder发出时,该命令不再起作用: public static void decompress7ZipEmbedded(File source, File destination) throws IOException, InterruptedExcepti

使用Java 10 ProcessBuilder和带有命令行的7z.exe(18.05)将归档文件提取到所需类别时遇到问题。当我使用Windows CMD时,该命令与预期的完全相同,但当我的JavaFX应用程序使用ProcessBuilder发出时,该命令不再起作用:

    public static void decompress7ZipEmbedded(File source, File destination) throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder(
            getSevenZipExecutablePath(),
            EXTRACT_WITH_FULL_PATHS_COMMAND,
            quotifyPath(source.getAbsolutePath()),
            OUTPUT_DIRECTORY_SWITCH + quotifyPath(destination.getAbsolutePath())
    );
    processWithSevenZipEmbedded(pb);
}

   private static void processWithSevenZipEmbedded(ProcessBuilder pb) throws IOException, InterruptedException {
    LOG.info("7-zip command issued: " + String.join(" ", pb.command()));
    Process p = pb.start();
    new Thread(new InputConsumer(p.getInputStream())).start();
    System.out.println("Exited with: " + p.waitFor());
}

   public static class InputConsumer implements Runnable {
        private InputStream is;

        InputConsumer(InputStream is) {
            this.is = is;
        }

        @Override
        public void run() {
            try {
                int value = -1;
                while ((value = is.read()) != -1) {
                    System.out.print((char) value);
                }
            } catch (IOException exp) {
                exp.printStackTrace();
            }
            LOG.debug("Output stream completed");
        }
    }

public static String getSevenZipExecutablePath() {
    return FileUtil.quotifyPath(getDirectory() + "7z" + "/" + "7z");
}

public static String quotifyPath(String path) {
    return '"' + path + '"';
}

public class Commands {

    public static final String EXTRACT_COMMAND = "e";
    public static final String EXTRACT_WITH_FULL_PATHS_COMMAND = "x";
    public static final String PACK_COMMAND = "a";
    public static final String DELETE_COMMAND = "d";
    public static final String BENCHMARK_COMMAND = "b";
    public static final String LIST_COMMAND = "l";

}

public class Switches {

    public static final String OUTPUT_DIRECTORY_SWITCH = "-o";
    public static final String RECURSIVE_SWITCH = "-r";
    public static final String ASSUME_YES = "y";
}
7-Zip 18.05 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2018-04-30

Scanning the drive for archives:
1 file, 59177077 bytes (57 MiB)

Extracting archive: D:\Pulpit\AppRack Sandbox\test\Something\Something 2\Something2.7z
--
Path = D:\Pulpit\AppRack Sandbox\test\Something\Something 2\Something2.7z
Type = 7z
Physical Size = 5917Exited with: 0
7077
Headers Size = 373
Method = LZMA2:26 LZMA:20 BCJ2
Solid = +
Blocks = 2


No files to process
Everything is Ok

Files: 0
Size:       0
Compressed: 59177077
该命令如下所示:

"C:/Users/blood/java_projects/AppRack/target/classes/7z/7z" x "D:\Pulpit\AppRack Sandbox\test\something\Something 2\Something2.7z" -o"D:\Pulpit\AppRack Sandbox\Something2"
C:/Users/blood/java_projects/AppRack/target/classes/7z/7z" x D:\Pulpit\AppRack Sandbox\test\Test\Test 2\Test.7z -oD:\Desktop\AppRack Sandbox\Test 2 -aoa
以及ProcessBuilder的输出:

    public static void decompress7ZipEmbedded(File source, File destination) throws IOException, InterruptedException {
    ProcessBuilder pb = new ProcessBuilder(
            getSevenZipExecutablePath(),
            EXTRACT_WITH_FULL_PATHS_COMMAND,
            quotifyPath(source.getAbsolutePath()),
            OUTPUT_DIRECTORY_SWITCH + quotifyPath(destination.getAbsolutePath())
    );
    processWithSevenZipEmbedded(pb);
}

   private static void processWithSevenZipEmbedded(ProcessBuilder pb) throws IOException, InterruptedException {
    LOG.info("7-zip command issued: " + String.join(" ", pb.command()));
    Process p = pb.start();
    new Thread(new InputConsumer(p.getInputStream())).start();
    System.out.println("Exited with: " + p.waitFor());
}

   public static class InputConsumer implements Runnable {
        private InputStream is;

        InputConsumer(InputStream is) {
            this.is = is;
        }

        @Override
        public void run() {
            try {
                int value = -1;
                while ((value = is.read()) != -1) {
                    System.out.print((char) value);
                }
            } catch (IOException exp) {
                exp.printStackTrace();
            }
            LOG.debug("Output stream completed");
        }
    }

public static String getSevenZipExecutablePath() {
    return FileUtil.quotifyPath(getDirectory() + "7z" + "/" + "7z");
}

public static String quotifyPath(String path) {
    return '"' + path + '"';
}

public class Commands {

    public static final String EXTRACT_COMMAND = "e";
    public static final String EXTRACT_WITH_FULL_PATHS_COMMAND = "x";
    public static final String PACK_COMMAND = "a";
    public static final String DELETE_COMMAND = "d";
    public static final String BENCHMARK_COMMAND = "b";
    public static final String LIST_COMMAND = "l";

}

public class Switches {

    public static final String OUTPUT_DIRECTORY_SWITCH = "-o";
    public static final String RECURSIVE_SWITCH = "-r";
    public static final String ASSUME_YES = "y";
}
7-Zip 18.05 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2018-04-30

Scanning the drive for archives:
1 file, 59177077 bytes (57 MiB)

Extracting archive: D:\Pulpit\AppRack Sandbox\test\Something\Something 2\Something2.7z
--
Path = D:\Pulpit\AppRack Sandbox\test\Something\Something 2\Something2.7z
Type = 7z
Physical Size = 5917Exited with: 0
7077
Headers Size = 373
Method = LZMA2:26 LZMA:20 BCJ2
Solid = +
Blocks = 2


No files to process
Everything is Ok

Files: 0
Size:       0
Compressed: 59177077
它没有任何作用。没有创建所需的文件夹,没有。使用CMD,它就像一个符咒一样工作(这里使用相同的命令从Windows 10 CMD登录)

你知道是什么导致了这里的差异吗?为什么它说“没有文件要处理,一切正常”,而不做任何事情?我已经尝试过首先使用File类创建一个文件夹,但似乎没有问题,因为在提取之前,无论目标文件夹是否存在,结果都是相同的


我已经尝试了所有我想到的方法,现在我的想法都没有了。请与我分享关于这个问题的任何建议。非常感谢。

非常感谢您的帮助


不要引用你的论点。引号用于命令shell。ProcessBuilder不是命令shell;它直接执行命令,因此任何引号都被视为参数本身(即文件名)的一部分。另外,pb.inheritIO();是查看子进程输出的更好方法,而不是手动使用进程流

谢谢@VGR,这似乎是问题所在-在我删除了上述命令中引用路径的方法之后,它就像一个符咒一样工作,并且提取归档文件没有任何问题!所以结论是,在使用Java ProcessBuilder时,我不应该在路径中使用引号

我还使用了pb.inheritIO(),您是对的,用这种方式管理它会更好、更容易

public static void decompress7ZipEmbedded(File source, File destination) throws IOException {
    ProcessBuilder pb = new ProcessBuilder().inheritIO().command(
            getSevenZipExecutablePath(),
            EXTRACT_WITH_FULL_PATHS_COMMAND,
            source.getAbsolutePath(),
            OUTPUT_DIRECTORY_SWITCH + destination.getAbsolutePath(),
            OVERWRITE_WITHOUT_PROMPT
    );
    processWithSevenZipEmbedded(pb);
}

private static void processWithSevenZipEmbedded(ProcessBuilder pb) throws IOException {
    LOG.info("7-zip command issued: " + String.join(" ", pb.command()));
    pb.start();
}

public class Commands {
    public static final String EXTRACT_WITH_FULL_PATHS_COMMAND = "x"; 
}

public class Switches {
    public static final String OUTPUT_DIRECTORY_SWITCH = "-o";
    public static final String OVERWRITE_WITHOUT_PROMPT = "-aoa";
}
双击文件7zip.chm或启动7-Zip并打开帮助并阅读帮助页面命令行版本-第一行7z[…]的语法[…]。我们已经清楚地解释过,首先必须指定命令x,其次应该是像-o这样的开关,最好的最后一个开关是--,然后是存档文件名和最后一个参数,比如要提取的文件/文件夹的名称。也可以在存档文件名之后指定开关,但不建议这样做,尽管帮助页上的-o示例末尾也带有-o

谢谢@Mofi提供的提示。我使用了-aoa开关而不是-y开关,它最终开始按我所希望的那样工作——在没有任何提示的情况下覆盖文件。我让命令的其余部分按照预期的方式工作,因此它最终看起来是这样的:

"C:/Users/blood/java_projects/AppRack/target/classes/7z/7z" x "D:\Pulpit\AppRack Sandbox\test\something\Something 2\Something2.7z" -o"D:\Pulpit\AppRack Sandbox\Something2"
C:/Users/blood/java_projects/AppRack/target/classes/7z/7z" x D:\Pulpit\AppRack Sandbox\test\Test\Test 2\Test.7z -oD:\Desktop\AppRack Sandbox\Test 2 -aoa

再次感谢您的帮助

不要引用你的论点。引号用于命令shell。ProcessBuilder不是命令shell;它直接执行命令,因此任何引号都被视为参数本身(即文件名)的一部分。另外,
pb.inheritIO()
是查看子进程输出的更好方法,而不是手动使用进程流。双击文件
7zip.chm
或启动7-Zip,打开帮助并阅读帮助页面命令行版本-第一行语法
7z[…][…]
。我们清楚地解释了,首先必须指定命令
x
,然后是开关,如
-o
,最好的最后一个开关是
--
,然后是存档文件名和最后一个参数,如要提取的文件/文件夹的名称。也可以在存档文件名之后指定开关,但不建议这样做,尽管
-o
的帮助页上的示例末尾也带有
-o