如何解决 LogOutputStream 中文乱码问题?

2022-04-15 17:17:40 +08:00
 ubuntuGary

不管是 org.apache.commons.exec 工具包,还是 org.zeroturnaround.exec 工具包,都会出现中文乱码问题,请问有办法解决吗? 例子: org.apache.commons.exec 工具包的 demo:

package utils.exec;

import cn.hutool.core.io.LineHandler;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.exec.*;

import java.util.concurrent.TimeUnit;

@Slf4j
public class LocalCommandUtils {
    private static final long TIMEOUT = 1;
    private static final TimeUnit TIME_UNIT = TimeUnit.DAYS;

    public static String execCmd(String cmd) {
        return execCmd(cmd, line -> {});
    }

    public static String execCmd(String cmd, LineHandler lineHandler) {
        return execCmd(cmd, lineHandler, TIMEOUT, TIME_UNIT);
    }

    public static String execCmd(String cmd, LineHandler lineHandler, @NonNull long timeout, @NonNull TimeUnit unit) {
        DefaultExecutor executor = new DefaultExecutor();
        ExecuteWatchdog watchdog = new ExecuteWatchdog(unit.toMillis(timeout));
        StringBuilder output = new StringBuilder();
        try {
            CommandLine cmdLine = CommandLine.parse(cmd);
            executor.setWatchdog(watchdog);
            executor.setStreamHandler(new PumpStreamHandler(new LogOutputStream() {
                @Override
                protected void processLine(String line, int logLevel) {
                    lineHandler.handle(line);
                    output.append(output.length() > 0 ? "\n" : "").append(line);
                }
            }));
            executor.execute(cmdLine);
            log.info("exec command:[{}] output:[\n{}\n]", cmd, output);
        } catch (Exception e) {
            log.error("exec command:[{}] failed, output:[\n{}\n]", cmd, output, e);
        }
        return output.toString();
    }

    public static void main(String[] args) {
        execCmd("ping 127.0.0.1", log::info);
    }
}

org.zeroturnaround.exec 工具包的 demo:

package utils.ztexec;

import cn.hutool.core.io.LineHandler;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.zeroturnaround.exec.ProcessExecutor;
import org.zeroturnaround.exec.stream.LogOutputStream;

import java.util.concurrent.TimeUnit;

@Slf4j
public class LocalCommandUtils {
    private static final long TIMEOUT = 1;
    private static final TimeUnit TIME_UNIT = TimeUnit.DAYS;

    public static String execCmd(String cmd) {
        return execCmd(cmd, line -> {});
    }

    public static String execCmd(String cmd, LineHandler lineHandler) {
        return execCmd(cmd, lineHandler, TIMEOUT, TIME_UNIT);
    }

    public static String execCmd(String cmd, LineHandler lineHandler, @NonNull long timeout, @NonNull TimeUnit unit) {
        StringBuilder output = new StringBuilder();
        try {
            new ProcessExecutor()
                    .commandSplit(cmd)
                    .timeout(timeout, unit)
                    .redirectOutput(new LogOutputStream() {
                        @Override
                        protected void processLine(String line) {
                            lineHandler.handle(line);
                            output.append(output.length() > 0 ? "\n" : "").append(line);
                        }
                    })
                    .execute();
            log.info("exec command:[{}] output:[\n{}\n]", cmd, output);
        } catch (Exception e) {
            log.error("exec command:[{}] failed, output:[\n{}\n]", cmd, output, e);
        }

        return output.toString();
    }

    public static void main(String[] args) {
        execCmd("ping 127.0.0.1", log::info);
    }
}
1328 次点击
所在节点    Java
2 条回复
ec0
2022-04-16 02:18:35 +08:00
研究了一下
这两个工具包在 github 上的代码,LogOutputStream 类都有设置 charset 的方法,但是是后来( 2020 、2021 年)加入的功能

而 maven 仓库里的版本(一个停留在 2014 年,一个停留在 2020 年)都没有设置 charset 的方法

所以你可以

1. 寻找其他的工具包

2. 抄 github 上的代码,比如

2.1 新建一个类 LogOutputStream ,把

https://github.com/zeroturnaround/zt-exec/blob/master/src/main/java/org/zeroturnaround/exec/stream/LogOutputStream.java

里的代码复制过去

2.2 将 import org.zeroturnaround.exec.stream.LogOutputStream; 改成 import 你自己的 LogOutputStream

2.3 在 new LogOutputStream 时设置 charset ,new LogOutputStream() {}.setOutputCharset("GBK")
ubuntuGary
2022-04-16 17:55:49 +08:00
@ec0 非常感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/847184

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX