java - 如何从 PrintStream 字节编码中恢复?

标签 java encoding

最新 SSCCEE

为什么下面的示例输出不同的字符串?

package tests.java;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.charset.Charset;
import java.util.Arrays;

public class Try_PrintWriterEncoding3 {

    public static void main(String[] args) {
        final PrintStream oldOut = System.out;

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new byte[] {(byte)b}, Charset.defaultCharset())); 
            }
        }));

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                throw new UnsupportedOperationException(); 
            }

            @Override
            public void write(byte[] b, int off, int len) throws IOException {
                oldOut.print(new String(Arrays.copyOf(b, len), Charset.defaultCharset()));
            }

            @Override
            public void write(byte[] b) throws IOException {
                throw new UnsupportedOperationException(); 
            }
        }));

        System.out.println("Привет, мир!");
    }
}

先前示例

我想编写自定义标准输出流,但国际编码失败。

据说,PrintStream按照默认编码将字符转换为字节。这可能意味着解码也应该使用默认编码。

但是这不起作用。

此外,任何其他可能的编码都不起作用。

package tests.java;

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import java.nio.charset.Charset;

public class Try_PrintWriterEncoding {

    public static void main(String[] args) {

        final PrintStream oldOut = System.out;

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.write(b); // works
            }
        }));

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new char[] {(char)b})); // does not work (garbage type 1)
            }
        }));

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new byte[] {(byte)b})); // does not work (garbage type 2)

            }
        }));

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new byte[] {(byte)b}, Charset.defaultCharset())); // does not work (garbage type 2)
            }
        }));

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new byte[] {(byte)b}, Charset.forName("UTF-8"))); // does not work (garbage type 2)
            }
        }));

        System.out.println("Привет, мир!");


        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new byte[] {(byte)b}, Charset.forName("CP866"))); // does not work (garbage type 3)
            }
        }));

        System.out.println("Привет, мир!");

        System.setOut(new PrintStream(new OutputStream() {

            @Override
            public void write(int b) throws IOException {
                oldOut.print(new String(new byte[] {(byte)b}, Charset.forName("Cp1251"))); // does not work (garbage type 4)
            }
        }));

        System.out.println("Привет, мир!");
    }
}

输出

enter image description here

最佳答案

改变

 }));

进入

 }), true, encoding);

其中 true 表示刷新换行符并根据需要进行编码,例如“Windows-1251”。

它永远不会在真实控制台上工作,因为这是操作系统定义的。

否则你必须像 IDE 那样伪造一个控制台。或者确保控制台(cmd.exe)为run under Unicode or so .

<小时/>
  System.setOut(new PrintStream(new OutputStream() {

        byte[] line = new byte[1024];
        int pos = 0;

        @Override
        public void write(int b) throws IOException {
            line[pos++] = (byte) b;
            if (pos >= line.length || b == '\n') {
                flush();
            }
        }

        @Override
        public void flush() throws IOException {
            oldOut.println(new String(line, 0, pos, ENCODING));
            oldOut.flush();
            pos = 0;
        }
    }), true, encoding);

首先尝试不提供 ENCODING,默认为操作系统的。

关于java - 如何从 PrintStream 字节编码中恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29283129/

相关文章:

java - 循环播种的排序算法

node.js - Nodejs - 使用 Dropbox Core API 下载 PDF 并保存到磁盘

PHP 修剪和空间不起作用

python - 当我在 Python 中使用 open(filename) 或在 C 中使用 fopen(filename) 时,保存文件的编码是什么?

postgresql - 我遇到无效的 UTF8 字节序列问题

java - 从 JAR 文件外部加载资源文件

java - 考虑捕获组中的空白

java - 字符串中的最后一个重复字符

java - 使用类加载器加载内部类

mysql - R 和 MySQL 的编码问题