Error_016 2023-06-06 08:50 采纳率: 27.3%
浏览 22

java中cmd管道通信关于BufferedWriter指定编码为GBK并调用Bandizip后BufferedReader读不到东西的问题


                        ProcessBuilder builder = new ProcessBuilder("cmd.exe");
                        builder.redirectErrorStream(true);
                        Process process = null;
                        try {
                            process = builder.start();
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }

                        BufferedReader br = null;
                        BufferedWriter bw = null;
                        try {
                            bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(),"GBK"));
                            br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
                        } catch (UnsupportedEncodingException ex) {
                            throw new RuntimeException(ex);
                        }
                        try {
                            String s;
                            bw.write("bz.exe x -o:"+out_path_label.getText()+" "+file_path_label.getText()+"\n");
                            bw.flush();
                            while (!(s = br.readLine()).equals("")){
                                System.out.println(s);
                                jta.append(s+"\n");
                            }
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }            

BufferedWriter和BufferedReader指定编码为GBK
BufferedWriter输出命令“bz.exe x -o:E:\【1】应用软件集\chatgpt\ E:\【1】应用软件集\chatgpt\mima.zip”
BufferedReader此时无法读出数据
控制台信息如下:

"C:\Program Files\Java\jdk-17\bin\java.exe" "-javaagent:F:\java\idea\IntelliJ IDEA Community Edition 2022.3.2\lib\idea_rt.jar=7375:F:\java\idea\IntelliJ IDEA Community Edition 2022.3.2\bin" -Dfile.encoding=UTF-8 -classpath "F:\java\projects\Zip Crack\out\production\Zip Crack" GUI
Microsoft Windows [版本 10.0.19045.2006]
(c) Microsoft Corporation。保留所有权利。
F:\java\projects\Zip Crack>bz.exe x -o:E:\【1】应用软件集\chatgpt\ E:\【1】应用软件集\chatgpt\mima.zip

然而同样的命令正常用cmd执行是这样的:

img


怎么办?
结尾附上完整源码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import java.nio.charset.StandardCharsets;

public class GUI extends JFrame {
    public GUI(){
        try {
            UIManager.setLookAndFeel(javax.swing.plaf.nimbus.NimbusLookAndFeel.class.getName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException |
                 UnsupportedLookAndFeelException e) {
            throw new RuntimeException(e);
        }
        Container co = getContentPane();
        setLayout(new GridLayout(5,1));
        JPanel file_path_panel = new JPanel();
        JLabel file_path_label = new JLabel("压缩包路径");
        JButton file_path_set_button = new JButton("打开...");
        JPanel out_path_panel = new JPanel();
        JPanel two_buttons_panel = new JPanel(new GridLayout(2,1));
        JLabel out_path_label = new JLabel("导出路径");
        JButton out_path_button = new JButton("解压到...");
        JButton out_path_this_button = new JButton("解压到当前文件夹");
        JTextArea jta = new JTextArea();
        jta.setLineWrap(true);
        JButton start_crack = new JButton("开始");
        JPanel crack_mode = new JPanel(new GridLayout(1,7));
        JCheckBox is_number = new JCheckBox("数字");
        JCheckBox is_alphabet = new JCheckBox("小写字母");
        JCheckBox is_alohabet_toUpperCase = new JCheckBox("大写字母");
        JCheckBox is_symbol = new JCheckBox("特殊字符");
        JTextField key_start_number = new JTextField();
        key_start_number.addKeyListener(new ControlTheInput());
        JLabel bolang = new JLabel("~");
        JTextField key_end_number = new JTextField();
        key_end_number.addKeyListener(new ControlTheInput());
        start_crack.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        ProcessBuilder builder = new ProcessBuilder("cmd.exe");
                        builder.redirectErrorStream(true);
                        Process process = null;
                        try {
                            process = builder.start();
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }

                        BufferedReader br = null;
                        BufferedWriter bw = null;
                        try {
                            bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(),"GBK"));
                            br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
                        } catch (UnsupportedEncodingException ex) {
                            throw new RuntimeException(ex);
                        }
                        try {
                            String s;
                            bw.write("bz.exe x -o:"+out_path_label.getText()+" "+file_path_label.getText()+"\n");
                            bw.flush();
                            while (!(s = br.readLine()).equals("")){
                                System.out.println(s);
                                jta.append(s+"\n");
                            }
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }
                        KeyDictionary kd = new KeyDictionary();
                        for(int i = Integer.parseInt(key_start_number.getText());i <= Integer.parseInt(key_end_number.getText());i++){
                            kd.init(is_number.isSelected(),is_alphabet.isSelected(),is_alohabet_toUpperCase.isSelected(),is_symbol.isSelected(),i);
                            String end_key = kd.get_end_key();
                            while (true){
                                String key = kd.GetKey()+"\n";
                                try {
                                    bw.write(key);
                                    bw.flush();
                                    String c = null;
                                    if (!read(c,jta,br)){
                                        break;
                                    }
                                } catch (IOException ex) {
                                    throw new RuntimeException(ex);
                                }
                                if (key.equals(end_key)){
                                    break;
                                }
                            }
                        }
                        try {
                            br.close();
                            bw.close();
                            process.destroy();
                        } catch (IOException ex) {
                            throw new RuntimeException(ex);
                        }

                    }
                }).start();
            }
        });

        file_path_set_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser file_path_chooser = new JFileChooser();
                file_path_chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                int i = file_path_chooser.showOpenDialog(getContentPane());
                if(i == JFileChooser.APPROVE_OPTION) {
                    File zip_file = file_path_chooser.getSelectedFile();
                    file_path_label.setText(zip_file.getAbsolutePath());
                }
            }
        });
        out_path_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser out_path_chooser = new JFileChooser();
                out_path_chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                int i = out_path_chooser.showOpenDialog(getContentPane());
                if(i == JFileChooser.APPROVE_OPTION) {
                    File out_path = out_path_chooser.getSelectedFile();
                    out_path_label.setText(out_path.getAbsolutePath());
                }
            }
        });
        out_path_this_button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String[] split = file_path_label.getText().split("\\\\");
                String new_file_path = file_path_label.getText().replace(split[split.length-1],"");
                out_path_label.setText(new_file_path);
            }
        });
        co.add(jta);
        file_path_panel.add(file_path_label,BorderLayout.CENTER);
        file_path_panel.add(file_path_set_button,BorderLayout.EAST);
        co.add(file_path_panel);
        two_buttons_panel.add(out_path_button);
        two_buttons_panel.add(out_path_this_button);
        out_path_panel.add(out_path_label);
        out_path_panel.add(two_buttons_panel);
        co.add(out_path_panel);
        crack_mode.add(is_number);
        crack_mode.add(is_alphabet);
        crack_mode.add(is_alohabet_toUpperCase);
        crack_mode.add(is_symbol);
        crack_mode.add(key_start_number);
        crack_mode.add(bolang);
        crack_mode.add(key_end_number);
        co.add(crack_mode);
        co.add(start_crack);
        setBounds(600,300,600,600);
        setVisible(true);
        setTitle("Zip Crack");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
    private boolean read(String c,JTextArea jta,BufferedReader br) {
        while (true){
            try {
                if ((c = br.readLine()) == null) break;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            jta.append(c+"\n");
            System.out.println(c);
            if (c.equals("Invalid password")){
                return true;
            }
        }
        return false;
    }
    class ControlTheInput extends KeyAdapter {

        public void keyTyped(KeyEvent e) {
            String key="0123456789"+(char)8;
            if(key.indexOf(e.getKeyChar())<0){
                e.consume();//如果不是数字则取消
            }
        }
    }
    public static void main(String[] args) {
        new GUI();
    }
}


展开全部

  • 写回答

1条回答 默认 最新

  • IT论之程序员 2023-06-07 13:40
    关注

    这个问题的原因是:

    1. cmd.exe的默认编码是GBK,而Java程序默认编码是UTF-8。
    2. 当你使用GBK编码写入数据到cmd.exe时,cmd.exe无法正确解析这些数据,因为它期望接收GBK编码的数据。
    3. 同理,当cmd.exe输出数据时,它使用GBK编码,但Java程序试图使用UTF-8解析这些数据,导致解析失败。
      解决方案有两个:
    4. 在启动cmd.exe时,指定其输入/输出编码为UTF-8。你可以这样做:
      java
      ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/K", "chcp 65001");
      // ...
      这会让cmd.exe使用UTF-8编码。
    5. 在Java代码中明确指出你要使用GBK编码读取和写入cmd.exe的数据。你应该这样做:
      java
      bw = new BufferedWriter(new OutputStreamWriter(process.getOutputStream(), "GBK"));
      br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
      像你的代码中已经做的一样。
      这两种方法任选一种都可以解决你的问题。我个人推荐第一种,使用UTF-8编码会更简单。
    评论
    编辑
    预览

    报告相同问题?

    问题事件

    • 创建了问题 6月6日

    悬赏问题

    • ¥20 对文档进行操作,有偿 有意向的可以加我v
    • ¥15 brainstorm进行致痫指数分析
    • ¥30 beeline连接hive集群会卡住
    • ¥15 julia语言画表面图
    • ¥15 前端css轮播图效果优化
    • ¥15 如何在已有的土地利用类型图中加入新的地类呢
    • ¥20 TCIA数据库下载报错,请问如何解决
    • ¥30 vue3使用@imgly/background-removal给图片去除背景
    • ¥60 一组二维图片转化成三维坐标,图片为种子虫道切片希望能三维重构提现虫道并且完成的那个虫道距离计算
    • ¥15 从mysql导入数据到hive
    手机看
    程序员都在用的中文IT技术交流社区

    程序员都在用的中文IT技术交流社区

    专业的中文 IT 技术社区,与千万技术人共成长

    专业的中文 IT 技术社区,与千万技术人共成长

    关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

    关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

    客服 返回
    顶部