JAVA使用16进制的unicode编码,而系统平台使用的是GBK编码.是不是表示数据在JAVA虚拟机里面的时候字符使用unicode编码表示的,而虚拟机向系统平台输出数据,系统平台又将接收的数据按照GBK编码来保存啊?
例如:输出一个英文字符到硬盘文件中,英文字符在虚拟机里面占两个字节,用的是unicode编码表示,当虚拟机输出英文字符到系统平台的文件中,而GBK编码的系统平台又将两个字节的英文字符转换成一个字节的英文字符了?
承认自己是帅哥或美女的 就指点我一下啊!!

解决方案 »

  1.   

    也就是说JAVA程序向GBK的平台的硬盘文件输出一个英文字符,这个英文字符会通过Write方法转成字节类型数据,然后再经过JVM编码和GBK编码吗??
    但是为什么虚拟机用ISO8859-1的方式将字符编码成字节输出到GBK平台的文件中会乱码啊?
      

  2.   

    JVM与OS之间到底是如何转化的,不清楚,反正是经过了转化
      

  3.   

    个人认为os不会转码的。。jvm给出的编码如果不相符就乱码了比如你往txt里面写文本,只有gbk才是中文。其他编码就乱码。等高人指点
      

  4.   

    字符在 JVM 中用的是unicode编码表示,这没错。这个问题的答案是否定的。这个过程是这样的JVM 在将字符输出时(无论输出到哪),都需要将字符转成字节进行输出(这个应该再有疑问,因为数据的保存和传输都是字节),如果你用字节流则需要手动的将要输出的字符转成字节,如果你用字符流,则需要为该字符流指定编码,或使用该字符流的默认编码。字符流在输出时会自动根据你指定的字符编码(或默认的字符编码)自动将字符转成字节进行传输。如果你的系统默认的字符编码是 GBK ,且将 JVM 中的一个英文字符保存到硬盘文件上的操作使用的是默认编码,那么在数据保存前,即传输过程中,已经是 1 个字节了。
      

  5.   


    也就是说虚拟机在创建字符(解码成Unicode)和输出字符时都是使用虚拟机的字符集或指定字符集进行输入(解码)和输出(编码)的吗?  当在程序中声明一个String s= "你好"; 时这个"你好"的字符是不是系统平台字符,然后虚拟机将这个系统平台字符解码成Unicode啊? 指点指点
      

  6.   


    被你绕晕了,哈哈。不是很清楚你要什么。随意给你解释吧:
    当你在一个 .java 文件中写 “String s= "你好";” 后,其实是将“你好”这两个字按照当前 .java 文件的编码格所规定的“你好”这两个字所对应的字节,包存到了 .java 文件中(虽然你看到了“你好”这两个字符,但你要始终认识到,文件中所保存的永远是字节)。当你编译该文件时,需要指定 .java 的文件编码,如果不指定则使用默认的(如果指定错了...后果可想而知...)。而在生成的 .class 中.“你好”这两个字是以 UNICODE 代码段保存的(其实也是字节,这些字节对应着 UNICODE 字符)。
      

  7.   


    就是说,在 .java 文件中写程序时,实际上就是按照 当前文件的 编码系统 将 我们写的数据 编码成 该数据在编码系统中对应的字节 来保存的. 而编译这个.java文件则是:用指定的编码,或默认的编码 对这个.java文件进行编码,编码成Unicode格式的.class文件,而在.class文件中将字节数据转换成字符的过程叫解码.不不是这样啊?
    "当前.java文件的编码"是不是指操作系统的编码?
      

  8.   

    “编码成Unicode格式的.class文件”? 
    设定的编码格式是在程序和系统中使用,若服务器,DB之间或有Web交互时,格式不符就会产生乱码
    不知道需要解决的问题是很什么,是讨论应用问题还是JVM运行机制,LZ最好能说明~
      

  9.   


    我就是想知道操作系统的字符集和虚拟机的字符集的区别.比如说在操作系统的一个 .java 文件里面写System.out.print("你好"); 这个"你好"是操作系统的数据还是虚拟机的数据.还有虚拟机和操作系统之间的字符传输用的是谁的编码系统.
      

  10.   

    “编码成Unicode格式的.class文件”?  
      

  11.   


    不好意思,误导了, .class 文件的编码格式应该是 UTF-8
      

  12.   


    老兄,加个QQ,这里等你的回答太难了
    我的QQ 33966794
      

  13.   

    .java文件和虚拟机是不是没有关系?对吧,java文件可以脱离虚拟机独立存在,所以我觉得这里的字符显示应该是用的操作系统的字符集,而传输或保存时用什么编码,就要看所在媒介供应方或维护方的要求了,只是一些个人看法
      

  14.   


    .Java 文件的编码类型,你是可以指定的。例如你在 Windows 下,通过记事本可以将 .java 文件保存为 ANSI 或 utf-8“编码”,和“解码”我没有太过关注这个定义。我个人认为正两个过程是相对的。你好像还没走出来,在文件中保存的不是字符,而是字节。你之所以看到了“你好”这两个“字符”,是因为操作系统根据某个“编码规则”在该规则对应的字符集中找到了“你好”这两个文字,并显示了出来。这个过程不关 JAVA 什么事,即时你通过 java 程序显示了某个字符,最终的显示工作仍旧是操作系统完成的,Java 程序所做的工作仅仅是把要显示的数据的“字节”和“编码规则”通知操作系统。然后操作系统在根据这些字节,和编码规则,到某个特定的字符集中寻找相应的字符图像,并显示出来(红色加粗部分,我没有亲眼见过。只是“编码过程”理解后,自己的认识,欢迎楼下拍砖)
      

  15.   


    "Java 程序所做的工作仅仅是把要显示的数据的“字节”和“编码规则”通知操作系统"
    指的是虚拟机将默认的编码规则或 指定的编码规则 通知操作系统,由系统来显示吗?(视频上说的是:将Unicode码转换为本地计算机所表示的代码的过程叫编码)虚拟机默认的编码规则是Unicode吧?
      

  16.   

    其实原来很弱智的,就是Jdk中有Unicode到各种编码的转换表。请参见 jre\lib\charsets.jar
      

  17.   


    从应用逻辑上来讲,应该是数据携带方将编码规则告知 数据解码显示方 显得更合乎逻辑,因为解码显示方(比如操作系统)是无法仅仅从数据信息中推理出编码信息的吧 数据和编码之间非确定性函数关系,一种数据信息码可能对应n种编码规则,即按照n种编码(此编码为名词)解码可得到不同结果。由此,我觉得应该是数据携带方将编码规则通过各种手段或途径告知 数据解码显示方,否则最终显示结果不可保证,肯定不对初衷。
    视频上说的是:将Unicode码转换为本地计算机所表示的代码的过程叫编码
    =============================================================
    怎么说呢,这句话我觉得还是有值得商榷的地方,所谓的编码,encode(动词)应该是一个明确而具体的概念,这里权且就认为不带泛指,encode:具体讲,就是将字符编译成码值,就是所谓编码(encode)
    而这里只是转码吧,或者有没有一种标准规定了此种情形也可以叫编码呢(不外乎一个标准制定问题)虚拟机默认的编码规则是Unicode吧?
    ================================
    是的吧,class文件有用UTF-8,虚拟机内部有用UTF-16,两者算来都是Unicode
      

  18.   

    我是这么认为的。而且自认为有道理。呵呵
    对于“编码”,和“解码”的概念,我没有这么理解。当然你可以这么认为,只要你明白这其中的真正含义是什么就可以。
    虚拟机使用的是 UNICODE 字符集,但是他支持多种“编码规则”。
      

  19.   


    比如说我从硬盘文件中读取一个GBK编码的文件到程序中,虚拟机是不是读取到GBK码值(GBK字符对应的字节数据)后,用虚拟机的编码规则 解码成Unicode对应的字符啊? 还有,这个解码的时候是以多少个字节为一个单位来解码的呢?(比如英文字符一个字节,中文字符两字节,虚拟机在读取到这些字节时怎么是知道那几个字节解码呢?)
      

  20.   

    首先Java在读文件时,不会考虑文件的编码格式,你甚至可以用 IO 流去读取“图像文件”。所以你说“虚拟机是不是读取到GBK码值”便不对。在 Java IO 流读取文件时,是将文件中保存的字节,读到内存中,然后根据需要可以选择将这些字节根据你指定的编码规则(我该如何理解你所说的“虚拟机的编码规则”啊?)进行编码,以得到一个 UNICODE 代码段。没研究过啊~~~看楼下的吧
      

  21.   


    "我该如何理解你所说的“虚拟机的编码规则”啊
    应该是指的就是虚拟机的file.encoding对应的值吧.也就是编码方式,这个file.encoding可以由程序指定,不知道大家的默认值是不是GBK,我的电脑默认是GBK."然后根据需要可以选择将这些字节根据你指定的编码规则进行编码"
    我觉得你说的这个编码应该叫解码吧? 将文件中读取的字节按照虚拟机的编码规则将字节数据解码成Unicode的字符.
    但是这个解码 是按照多少个字节为一个单位来解码的呢??(比如英文字符一个字节,中文字符两字节,虚拟机在读取到这些字节时怎么是知道那几个字节解码呢?)
      

  22.   

    我理解这里有不止一个步骤,先GBK码值-转为字符-转为Unicode码值以几个字节解码是受编码决定的吧,比如在GBK中英文字符就是一个字节解码,汉字就是两个
      

  23.   

    我不能确定是否数据都是以字节传输,关于这点或许我们可以另外集中讨论。对于某个中文字符而言,在未确定是用什么编码解码的之前,是无法知道它具体是对应几个字节的,一旦明确了它的编码,它对应的字节也就确定了,我们不妨将编码设为映射关系f,字符是x,那么会有关系式: 
    字节数据y=f(x),反身特性 x=g(y) 两者都是唯一确定关系
    也就是说某个中文字符在某个编码关系中对应什么,一个字节还是两个字节,还是几个字节,什么字节内容,都是由它事先确定了的,我是这样认识的。
      

  24.   

    俺也来说两句
    看到的都是系统的东西,java只不过是个中间的东西
    你可以直接调用系统API,不用javaIO也可以,至于编码解码就是数值转换。
    看到上面的讨论,呵呵,感觉很乱
      

  25.   


    "我不能确定是否数据都是以字节传输,关于这点或许我们可以另外集中讨论。"
    数据的保存不都是以字节来保存的吗?(在视频说的是:文件的保存永远都是字节) 我们看到的字符不都是用编
    码规则 将字节解码出来的吗? 既然是字节保存的,那么在输入或输出的时候应该都是以字节为单位传输啊?"也就是说某个中文字符在某个编码关系中对应什么,一个字节还是两个字节,还是几个字节,什么字节内容,都是由它事先确定了的,我是这样认识的。"
    你说的 "中文字符在编码规则中占几个字节,这几个字节的值是多少,都由编码规则确定了" 是不是指这些确定了的字节为一个"数据段"?(我不知道怎么称呼这几个确定的字节) 
    综合你的意思,我是不是应该理解成:数据在传输时,是以"数据段"进行解码的? 比如:从GBK的中文字符2个字节为一个"数据段",英文的为一个"数据段",解码的时候是按这个"数据段"为单位进行解码的?
    请指点
      

  26.   

    在面向字符编解码的领域里,最小数据单元就是字节(一个英文字符可对应一个字节),那你要说成数据段也无不可
    可以把编码规则看成是一个从字节组到字符的函数映射表,从字节组到字符是一一映射,反之也应该是(否则无法在此编码规则下对此字符编码)比如GBK中:
    0x61 <=> a
    0x62 <=> b
    0xd6d0 <=> 中
    0xb9fa <=> 国
      

  27.   


    就是有一个关键的问题我没理解: 英文1字节,中文字符2字节, 将 "a你b好" 这6个字节读取到一个byte数组里面时 在byte数组里面不就是6个 byte类型的值 吗? 然后用new String(byte[],0,len)将byte数组解码成字符串.那编码规则是怎么知道将 'a' 为一个字节组 解码 又将 '你' 为一个字节组解码的呢?  问题的关键啊...
      

  28.   

    对于某个中文字符而言,在未确定是用什么编码解码的之前,是无法知道它具体是对应几个字节的,一旦明确了它的编码,它对应的字节也就确定了,我们不妨将编码设为映射关系f,字符是x,那么会有关系式:  
    字节数据y=f(x),反身特性 x=g(y) 两者都是唯一确定关系
    也就是说某个中文字符在某个编码关系中对应什么,一个字节还是两个字节,还是几个字节,什么字节内容,都是由它事先确定了的,我是这样认识的。
      

  29.   

    查了维基,是这样的,高字节是不会和单字节范围冲突的:字符有一字节和双字节编码,00–7F范围内是一位,和ASCII保持一致,此范围内严格上说有96个文字和32个控制符号。之后的双字节中,前一字节是双字节的第一位。总体上说第一字节的范围是81–FE(也就是不含80和FF),第二字节的一部分领域在40–FE,其他领域在80–FE。
    GBK编码表
    [url=http://www.360doc.com/content/05/0801/15/305_4166.shtml]
      

  30.   

    维基:
    http://zh.wikipedia.org/zh/GBKGBK编码表:
    http://www.360doc.com/content/05/0801/15/305_4166.shtml
      

  31.   

    没有,我不是这个意思可以说首字节的内容在GBK中就决定了此字符是几个字节 汉字高字节和ascii码值是不冲突的
      

  32.   

    不是。
    比如GBK中,它有对应一个字节的字符,也有对应两个字节的字符,一个字节字符的字节内容同两个字节字符高字节(也即首字节)的内容是不交叉的,也就是不可能有相同的情况出现,它们是分别位于不同的区段内的。因此只要判断首字节位于哪个区段就能知道该字符在此编码规则中对应几个字节。
      

  33.   


    哦,也就是说根据字符的首字节的区段来决定 多少个字节进行解码的吧."区段信息和字节数信息是共生绑定的"
    这句话是指:每个区段都规定(绑定) 了多少个字节吗?还有个题外题,也想请你指点指点,就是 一字节字符 为什么和 两字节字符首字节 的内容不可能相同? 比如说一字节'a'字符的值为0x61. 那两字节字符的首字节为什么不能是 0x61.. 呢?
      

  34.   

    对对,每个区段是固定字节数,看那个维基中解释:
    00–7F范围内是一字节编码
    81–FE(也就是不含80和FF)范围内是双字节编码
    对应什么码是人为设定的,如果相同就冲突了,设计时就得避开
      

  35.   


    哦,原来是这样,谢谢了.
    我印象中好像视频上(或书)上说过一句和你类似话,当时不是很理解
    好像是说中文为了和英文区分开来,GBK首字节的高位用1来表示.(不知道是不是完全这样说的)
    Ascll码是127种字符,也就是7个比特位,高位为0.
    不知道那个视频说的是不是指 你的这句话!
      

  36.   

    java的io是字节为单位的。如果你要以char为单位进行读写的话,是需要知道字符编码的。如果没有制定的话是以系统默认的字符集编解码的。如果系统默认的字符集编码当前虚拟机不支持的话,就会用iso-8859什么这个编解码。至于怎么编解码的,你可以看看charsetencoder和charsetdecoder这两个类。每个的字符集的编解码都有自己的编解码方式。如果你以utf-8编码的文件指定gbk进行解码的话,读出来的字符就是乱码了。这个字符在内存中是以utf-16编码的,也就说假定你用gbk解码出来的字符是“人”字,那么在内存中保持的是“人”字对应的utf-16的编码。
      

  37.   

    是的,00-7F 对应二进制 00000000 - 01111111 128个字符最高bit位都是0
    81–FE 对应二进制 10000001 - 11111110 126个字符最高bit位都是1此特征是可以借以判断的