ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

查询从“ UTF-8”世界到Java“ char”的读取字节

2019-11-20 23:03:39  阅读:232  来源: 互联网

标签:bytebuffer character-encoding nio java


有了此link中提供的以下代码段,

byte[] bytes = {0x00, 0x48, 0x00, 0x69, 0x00, 0x2C,
                      0x60, (byte)0xA8, 0x59, 0x7D, 0x00, 0x21};  // "Hi,您好!"

Charset charset = Charset.forName("UTF-8");
// Encode from UCS-2 to UTF-8
// Create a ByteBuffer by wrapping a byte array
ByteBuffer bb = ByteBuffer.wrap(bytes);
// Create a CharBuffer from a view of this ByteBuffer
CharBuffer cb = bb.asCharBuffer();

使用wrap()方法,“新的缓冲区将由给定的字节数组支持”,这里我们没有从字节到其他格式的任何编码,它只是将字节数组放在缓冲区中.

cb与字符数组相似时,请您帮我理解,当我们在上面的代码中说bb.asCharBuffer()时,我们到底在做什么?由于char在Java中是UTF-16,因此使用asCharBuffer()方法,我们是否会将bb中的每2个字节视为char?这是正确的方法吗?如果没有,请以正确的方式帮助我.

编辑:
我按照下面的Meisch的建议尝试了该程序,

byte[] bytes = {0x00, 0x48, 0x00, 0x69, 0x00, 0x2C,
                0x60, (byte)0xA8, 0x59, 0x7D, 0x00, 0x21};  // "Hi,您好!"

        Charset charset = Charset.forName("UTF-8");
        CharsetDecoder decoder = charset.newDecoder();
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        CharBuffer cb = decoder.decode(bb);

这给了例外

Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(Unknown Source)
    at java.nio.charset.CharsetDecoder.decode(Unknown Source)
    at TestCharSet.main(TestCharSet.java:16)

请帮助我,被困在这里!!!

注意:我正在使用Java 1.6

解决方法:

您会问:“因为char是Java中的UTF-16,使用asCharBuffer()方法,我们是否将bb中的每2个字节视为char?”

这个问题的答案是肯定的.您的理解是正确的.

您的下一个问题是:“这是正确的方法吗?”

如果您只是想演示ByteBuffer,CharBuffer和Charset类的工作方式,那是可以接受的.

但是,在编写应用程序代码时,您将永远不会像这样编写代码.首先,不需要字节数组.您可以将字符表示为文字字符串:

String s = "Hi,\u60a8\u597d!";

如果要将字符串转换为UTF-8字节,只需执行以下操作:

byte[] encodedBytes = s.getBytes(StandardCharsets.UTF_8);

如果您仍在使用Java 6,则可以执行以下操作:

byte[] encodedBytes = s.getBytes("UTF-8");

更新:您的字节数组以UTF-16BE(大端)编码表示字符.具体来说,您的数组每个字符正好有两个字节.这不是有效的UTF-8编码的字节序列,这就是为什么要获取MalformedInputException的原因.

当字符编码为UTF-8字节时,每个字符将用1到4个字节表示.为了使第二段代码正常工作,该数组必须为:

byte[] bytes = {
    0x48, 0x69, 0x2c,                       // ASCII chars are 1 byte each
    (byte) 0xe6, (byte) 0x82, (byte) 0xa8,  // U+60A8
    (byte) 0xe5, (byte) 0xa5, (byte) 0xbd,  // U+597D
    0x21
};

从字节转换为char时,我的先前声明仍然适用:您不需要ByteBuffer或CharBuffer或Charset或CharsetDecoder.您可以使用这些类,但是通常创建一个String更为简洁:

String s = new String(bytes, "UTF-8");

如果需要CharBuffer,只需包装字符串:

CharBuffer cb = CharBuffer.wrap(s);

您可能想知道什么时候适合直接使用CharsetDecoder.如果这些字节来自不受您控制的源,并且您有充分的理由相信它可能不包含正确的UTF-8编码字节,则可以这样做.使用显式的CharsetDecoder可让您自定义如何处理无效字节.

标签:bytebuffer,character-encoding,nio,java
来源: https://codeday.me/bug/20191120/2047547.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有