如何在Linux上用Java解压受密码保护的7zip存档?

如何在Linux上用Java解压受密码保护的7zip存档?,java,ubuntu,7zip,Java,Ubuntu,7zip,在我的项目中,我们需要从密码保护的7zip存档中提取文件。 我的源代码如下: try { ProcessBuilder pb = new ProcessBuilder("7z", "e", "bootstrap.7z", "-so", "bootstrap.txt"); Process p = pb.start(); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputS

在我的项目中,我们需要从密码保护的7zip存档中提取文件。
我的源代码如下:

try {
    ProcessBuilder pb = new ProcessBuilder("7z", "e", "bootstrap.7z", "-so", "bootstrap.txt");
    Process p = pb.start();
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
    BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));

    writer.write("password" + "\n");
    writer.flush();
    writer.close();

    String line = null;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch  (IOException e) {
    e.printStackTrace();
}
上述代码块不起作用。
虽然我已经通过BufferedWriter传递了密码,但在运行java程序时仍然需要手动输入密码

出于安全原因,在创建子进程时,我不能使用参数“-p”将密码传递给7z(如果进程“7z”挂起,客户可以通过命令“ps aux | grep 7z”从进程信息中查看密码)

你能在我的代码里找出这个问题吗?我的java版本是1.8,操作系统是Ubuntu 16.04


非常感谢。

您不能使用std.out键入某些命令行程序,因为它们不读取std.out,只读取键盘上输入的符号。我相信,当您使用命令行输入7z的密码时,情况就是这样。为了能够输入此密码,您需要启动一个控制台窗口,然后模拟键盘的行为,这样就好像有人在窗口中真正输入密码一样。您可以使用java Robot类来实现这一点。我有一个Keyborad类,它包含机器人,以简化键入过程。请注意,在系统的键盘类中,某些特殊字符可能需要以不同的方式键入,因此需要对此进行调整。下面是一些适用于您的案例和Keyboard.java实现的伪代码(适用于windows,但在linux中应该很容易转换):

public static void run7z() throws IOException, InterruptedException {
    startCommandLineShell();
    waitABit();
    keyboard.type("7z.exe e bootstrap.7z -so bootstrap.txt").enter();
    waitABit();
    keyboard.type("yourSecretPasswordHere").enter();
}

private static void startCommandLineShell() throws IOException {
    Runtime.getRuntime().exec(new String[] { "C:\\Windows\\system32\\cmd.exe", "/C", "start" });
}
和键盘类:

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;

public class Keyboard {

    private Robot robot;

    public static void main(String... args) throws Exception 
    {

        Keyboard keyboard = new Keyboard();
        keyboard.type("~!@#$%^&*()_+");
    }

    public Keyboard()
    {
        try {
            this.robot = new Robot();
            robot.delay(500);
            robot.setAutoDelay(2);
            robot.setAutoWaitForIdle(true);
        } catch (AWTException e) {
            throw new RuntimeException(e);
        }
    }

    public Keyboard(Robot robot) 
    {
        this.robot = robot;
    }

    public Keyboard type(CharSequence characters) 
    {
        int length = characters.length();
        for (int i = 0; i < length; i++) 
        {
                char character = characters.charAt(i);
                type(character);
        }
        return this;
    }

    public void enter()
    {
      robot.keyPress(KeyEvent.VK_ENTER);
    }

    public void type(char character) 
    {
        try {
        switch (character) {
        case 'a': doType(KeyEvent.VK_A); break;
        case 'b': doType(KeyEvent.VK_B); break;
        case 'c': doType(KeyEvent.VK_C); break;
        case 'd': doType(KeyEvent.VK_D); break;
        case 'e': doType(KeyEvent.VK_E); break;
        case 'f': doType(KeyEvent.VK_F); break;
        case 'g': doType(KeyEvent.VK_G); break;
        case 'h': doType(KeyEvent.VK_H); break;
        case 'i': doType(KeyEvent.VK_I); break;
        case 'j': doType(KeyEvent.VK_J); break;
        case 'k': doType(KeyEvent.VK_K); break;
        case 'l': doType(KeyEvent.VK_L); break;
        case 'm': doType(KeyEvent.VK_M); break;
        case 'n': doType(KeyEvent.VK_N); break;
        case 'o': doType(KeyEvent.VK_O); break;
        case 'p': doType(KeyEvent.VK_P); break;
        case 'q': doType(KeyEvent.VK_Q); break;
        case 'r': doType(KeyEvent.VK_R); break;
        case 's': doType(KeyEvent.VK_S); break;
        case 't': doType(KeyEvent.VK_T); break;
        case 'u': doType(KeyEvent.VK_U); break;
        case 'v': doType(KeyEvent.VK_V); break;
        case 'w': doType(KeyEvent.VK_W); break;
        case 'x': doType(KeyEvent.VK_X); break;
        case 'y': doType(KeyEvent.VK_Y); break;
        case 'z': doType(KeyEvent.VK_Z); break;
        case 'A': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_A); break;
        case 'B': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_B); break;
        case 'C': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_C); break;
        case 'D': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_D); break;
        case 'E': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_E); break;
        case 'F': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_F); break;
        case 'G': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_G); break;
        case 'H': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_H); break;
        case 'I': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_I); break;
        case 'J': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_J); break;
        case 'K': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_K); break;
        case 'L': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_L); break;
        case 'M': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_M); break;
        case 'N': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_N); break;
        case 'O': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_O); break;
        case 'P': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_P); break;
        case 'Q': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_Q); break;
        case 'R': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_R); break;
        case 'S': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_S); break;
        case 'T': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_T); break;
        case 'U': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_U); break;
        case 'V': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_V); break;
        case 'W': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_W); break;
        case 'X': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_X); break;
        case 'Y': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_Y); break;
        case 'Z': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_Z); break;
        case '`': doType(KeyEvent.VK_BACK_QUOTE); break;
        case '0': doType(KeyEvent.VK_0); break;
        case '1': doType(KeyEvent.VK_1); break;
        case '2': doType(KeyEvent.VK_2); break;
        case '3': doType(KeyEvent.VK_3); break;
        case '4': doType(KeyEvent.VK_4); break;
        case '5': doType(KeyEvent.VK_5); break;
        case '6': doType(KeyEvent.VK_6); break;
        case '7': doType(KeyEvent.VK_7); break;
        case '8': doType(KeyEvent.VK_8); break;
        case '9': doType(KeyEvent.VK_9); break;
        case '-': doType(KeyEvent.VK_MINUS); break;
        case '=': doType(KeyEvent.VK_EQUALS); break;
        case '~': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE); break;
        case '!': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_1); break;//doType(KeyEvent.VK_EXCLAMATION_MARK); break;
        case '@': doType(KeyEvent.VK_AT); break;
        case '#': doType(KeyEvent.VK_NUMBER_SIGN); break;
        case '$': doType(KeyEvent.VK_DOLLAR); break;
        case '%': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_5); break;
        case '^': doType(KeyEvent.VK_CIRCUMFLEX); break;
        case '&': doType(KeyEvent.VK_AMPERSAND); break;
        case '*': doType(KeyEvent.VK_ASTERISK); break;
        case '(': doType(KeyEvent.VK_LEFT_PARENTHESIS); break;
        case ')': doType(KeyEvent.VK_RIGHT_PARENTHESIS); break;
        case '_': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_MINUS); break;
        case '+': doType(KeyEvent.VK_PLUS); break;
        case '\t': doType(KeyEvent.VK_TAB); break;
        case '\n': doType(KeyEvent.VK_ENTER); break;
        case '[': doType(KeyEvent.VK_OPEN_BRACKET); break;
        case ']': doType(KeyEvent.VK_CLOSE_BRACKET); break;
        case '\\': doType(KeyEvent.VK_BACK_SLASH); break;
        case '{': doType(KeyEvent.VK_SHIFT, KeyEvent. VK_OPEN_BRACKET); break;
        case '}': doType(KeyEvent.VK_SHIFT, KeyEvent. VK_CLOSE_BRACKET); break;
        case '|': doType(KeyEvent.VK_SHIFT, KeyEvent. VK_BACK_SLASH); break;
        case ';': doType(KeyEvent.VK_SEMICOLON); break;
        case ':': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_SEMICOLON); break;
        case '\'': doType(KeyEvent.VK_QUOTE); break;
        case '"': doType(KeyEvent.VK_QUOTEDBL); break;
        case ',': doType(KeyEvent.VK_COMMA); break;
        case '<': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_COMMA); break;//doType(KeyEvent.VK_LESS); break;
        case '.': doType(KeyEvent.VK_PERIOD); break;
        case '>': doType(KeyEvent.VK_SHIFT,KeyEvent.VK_PERIOD); break;
        case '/': doType(KeyEvent.VK_SLASH); break;
        case '?': doType(KeyEvent.VK_SHIFT, KeyEvent.VK_SLASH); break;
        case ' ': doType(KeyEvent.VK_SPACE); break;
//        default:  doType(KeyEvent.getExtendedKeyCodeForChar(character));
//                throw new IllegalArgumentException("Cannot type character " + character);
        }
        } catch (Exception e) {
            System.out.println(e+" Can't type characer: "+character);
        }
    }

    private void doType(int... keyCodes) 
    {
        doType(keyCodes, 0, keyCodes.length);
    }

    private void doType(int[] keyCodes, int offset, int length) 
    {
        if (length == 0) 
            return;

        robot.keyPress(keyCodes[offset]);
        doType(keyCodes, offset + 1, length - 1);
        robot.keyRelease(keyCodes[offset]);
    }

}
import java.awt.AWTException;
导入java.awt.Robot;
导入java.awt.event.KeyEvent;
公共类键盘{
私人机器人;
公共静态void main(字符串…参数)引发异常
{
键盘=新键盘();
键盘。键入(“~!@$%^&*()\”;
}
公用键盘()
{
试一试{
this.robot=新机器人();
机器人延时(500);
机器人。设置自动延迟(2);
robot.setAutoWaitForIdle(真);
}捕获(awtexe){
抛出新的运行时异常(e);
}
}
公用键盘(机器人)
{
这个机器人=机器人;
}
公用键盘类型(字符序列字符)
{
int length=characters.length();
for(int i=0;i