最新的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("Привет, мир!");
}
}
输出
答案 0 :(得分:1)
更改
}));
到
}), 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,默认为操作系统的。