Java - SCP 之后的“ü/ä/ö”问题

Java - Problems with "ü/ä/ö" after SCP

我创建了一个可以加载本地或远程日志文件的程序。 如果我加载本地文件,则没有错误。 但是,如果我先将带有 SCP 的文件复制到我的本地(我使用此代码的地方:http://www.jcraft.com/jsch/examples/ScpFrom.java.html)并读出它,我会收到错误消息,字母“ü/ä/ö”显示为�。 我该如何解决这个问题?

远程:Linux-服务器 本地:Windows-PC

SCP 代码:

http://www.jcraft.com/jsch/examples/ScpFrom.java.html

读出代码:

protected void openTempRemoteFile() throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream( lfile )));
        String strLine;

        DefaultTableModel dtm = new DefaultTableModel(0, 0);
        String header[] = new String[]{ "Timestamp", "Session-ID", "Log" };
        dtm.setColumnIdentifiers(header);
        table.setModel(dtm);

        while ((strLine = reader.readLine()) != null) {     

            String[] sparts = strLine.split(" ");
            String[] bparts = strLine.split("   : ");

            String Timestamp = sparts[0] + " " + sparts[1];
            String SessionID = sparts[4];
            String Log = bparts[1];

            dtm.addRow(new Object[] {Timestamp, SessionID, Log});
        }
        reader.close();
}

编辑:

本地文件编码格式:UTF-8

来自Linux-服务器的SCP-远程文件的编码格式:WINDOWS-1252

InputStreamReader 构造函数提供适当的 Charset,例如:

import java.nio.charset.StandardCharsets;

...

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
        new FileInputStream( lfile ),
        StandardCharsets.UTF_8)); // try also ISO_8859_1 if UTF_8 doesn't help.

使用编码是一件非常棘手的事情。如果您的系统总是使用这种文件(来自不同的环境),那么您应该首先检测字符集,而不是使用给定的字符集读取它。我有类似的问题,我用过 juniversalchardet 检测字符集并使用 InputStreamReader(stream, Charset)。 在你的情况下,它就像

protected void openTempRemoteFile() throws IOException {
        String encoding = UniversalDetector.detectCharset(lfile);
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream( lfile ), Charset.forName(encoding)));
        ....

如果它只是一次工作而不是在文本编辑器(例如 notapad++)中打开它而不是将它保存在您的编码中。比在程序中使用它。

要解决您的问题,您至少有两个选择:

您可以直接在代码中指定文件的编码,更新如下:

BufferedReader reader = new BufferedReader(
    new InputStreamReader(
        new FileInputStream( lfile ),
        "UTF8"
    )
);

或设置启动 JVM 时的默认文件编码:

java -Dfile.encoding=UTF-8 … com.example.Main

我绝对喜欢第一种方式,如果需要,您也可以参数化 "UTF8" 值。 使用后一种方法,如果您忘记指定,您仍然可能会遇到同样的问题。

您可以将编码替换为您喜欢的任何编码(请参阅 https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html 了解支持的编码),并且在 Windows 上,"Cp1252" 通常是默认编码。

请记住,您始终可以使用查询 file.encoding 属性 或 Charset.defaultCharset() 来查找应用程序的当前默认编码,例如:

byte [] byteArray = {'blablabla'};
InputStream inputStream = new ByteArrayInputStream(byteArray);
InputStreamReader reader = new InputStreamReader(inputStream);
String defaultEncoding = reader.getEncoding();