想在命令行窗口输出中文,windows vista英文版, system locale里编码已经设置为gbk. 
试了很久,发现如下的代码可行,但是不知道为什么对于console需要先转成gbk然后按cp1252编码?而输出到GUI却不需要。实在不解。import javax.swing.*;
import java.io.*;
class Tester {
public static void main(String[] args) throws IOException {
String msg="测试字符串";
byte[] bmsg=msg.getBytes("gbk");
String mmsg=new String(bmsg,"CP1252");
System.out.println(mmsg);
JOptionPane.showMessageDialog(null,msg);
}
}

解决方案 »

  1.   

    java输出到console的字符集是根据系统字符集自动转换的啊..
    不知道你这个问题是怎么出现的...
      

  2.   

    刚刚又试了一下不同版本的jre,发现jre1.4.2没问题,jre1.5.0和jre1.6.0都存在这个问题。
    shadowlin说的没错,的确是根据系统字符集定的,问题是jre5和6似乎都判断错了系统字符集。
    用System.getProperty("file.encoding"),在jre5和6里显示cp1252,而jre4显示gbk.显然jre4是对的。
    搞不懂是jre的问题,还是我的windows系统的问题?Java是怎样确定系统字符集的呢?显然不同版本实现用的方法还不一样。
      

  3.   

    我觉的你最好试一下  ISO-8859-1编码
      

  4.   

    byte[] bmsg=msg.getBytes("gbk"); 
    String mmsg=new String(bmsg,"CP1252"); 楼主这两段代码
    第一行, 先把msg转成gbk的编码的, 也就是说bmsg字节数组是用的gbk编码,
    而new String,又使用CP1252编码, 如果不兼容, 肯定要乱码啊
    bmsg是GBK编码的,怎么能当成是CP1252编码的呢```楼主似乎对java的编码转换理解不透彻, 应该好好补补功课System.out 的类型是java.io.PrintStream, 已经是字符型的输出流了,只会接受String或者说Char, 也就是说它的编码必须是Unicode码的,楼主把msg转换了已经是乱码了, 不可能再与Unicode兼容如果楼主需要改变控制台输出流的编码, 应该改变System.out的默认编码, 而不是改变String, String不存在转码, 因为他是Unicode码的, 只有byte[]才会有匹配的编码标准既然JVM初使化时已经将System.out,设定为字符的输出流,而不是字节的输出流, 那说明JVM可以识别控制台的编码方式,它会自动将Unicode的文本,转换为控制码编码的字节流, 传到操作系统中, 如果转换出了错, 说明是JDK的BUG,应该找JDK的开发商.
    如果楼主确实需要更改编码的话, 请参考
    System.initializeSystemClass()方法
    其中有段代码是这样的
    FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
    FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
    FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
    setIn0(new BufferedInputStream(fdIn));
    setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true));
    setErr0(new PrintStream(new BufferedOutputStream(fdErr, 128), true));如果要更改编码方式, 应该在new PrintStream时, 显式指定编码方式,
    如果没有指定, 则PrintStream, 会采用默认编码方式, 而默认编码方式, 是从系统属性file.encoding中获取的,
    即使用以下方式获取System.getProperty("file.encoding", "ISO-8859-1");楼主可以在启动java程序时, 在命令行中指定 -Dfile.encoding=CP1252, 看这样是否能解决问题
      

  5.   

    谢谢seaver详尽的回答。
    下面这两行代码本来我是没加的
    byte[] bmsg=msg.getBytes("gbk"); 
    String mmsg=new String(bmsg,"CP1252");
    可是发现出乱码,所以才加上去,加上反而正常了,所以一直不解。现在我基本确定问题出在JVM识别控制台的编码方式,这个好像在中文windows下不会有问题,但是在英文windows系统下,jdk5和6始终识别为cp1252. jdk4就能正常识别为gbk. 问题应该出在jdk5/6并没有读取system locale的设置。用
    java -Dfile.encoding=GBK xxx
    强制修改系统属性file.encoding的确解决了问题,上面两行四不像的代码终于可以去掉了。
    再次感谢
      

  6.   

    对于那两行代码
    byte[] bmsg=msg.getBytes("gbk"); 
    String mmsg=new String(bmsg,"CP1252"); 
    我的理解是这样:
    我的console是gbk编码的,而jdk错误识别成cp1252,所以它会把字符都转成cp1252编码输出给console。
    现在msg先转成gbk编码的字节,然后按cp1252编码变成unicode的String,这样jdk再做unicode->cp1252以后就正好得到gbk编码的字节,传给console就现实正常了。