Java 如何从PrintStream字节编码中恢复?
最新SSCCEE 为什么下面的示例输出不同的字符串Java 如何从PrintStream字节编码中恢复?,java,encoding,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
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("Привет, мир!");
}
}
输出
改变
}));
进入
其中true表示换行符刷新,并根据需要进行编码,如“Windows-1251”
它永远不会适用于真正的控制台,因为这是操作系统定义的
否则,您必须像IDE一样伪造控制台。或者确保控制台(cmd.exe)处于打开状态
首先,请尝试不提供默认为操作系统的编码。您在哪里运行此程序?您的标准输出显示在哪里?标准输出显示在Eclipse控制台内,但这并不重要,因为两个输出的方式相同,应该给出相同的结果。当
字节到达支持打印流的输出流时,它已经被编码。覆盖写入
时,您试图执行什么操作?进入写入
时使用哪些编码字节?默认字符编码,或作为构造函数参数提供的编码。请参阅javadoc。我不应该触摸PrintStream
,我应该从它的字节中恢复。问题是如何从默认PrintStream
工作结果中出现的字节中提取正确的符号。那么您是在文件中捕获字节的吗?然后你可以在记事本++或JEdit之类的程序员编辑器中打开该文件,并切换编码;在任何情况下,字节转换都是不现实的。您需要为输入行创建一个字节数组,并使用新字符串(字节,编码)
转换它。是的,我也这么认为。看起来PrintStream没有使用单字节编码。
}), true, encoding);
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);