【问题标题】:Reading two bytes from array of bytes从字节数组中读取两个字节
【发布时间】:2012-12-11 20:16:30
【问题描述】:

我正在用 Java 创建一个简单的应用程序,它允许我读取文本文件。我有一个包装在 ByteBuffer 中的字节数组:

 FileInputStream inputStream = new FileInputStream(name);
 FileChannel channel = inputStream.getChannel();
 byte[] bArray = new byte[8192];
 ByteBuffer byteBuffer = ByteBuffer.wrap(bArray);
 int read;

然后我使用 while 循环遍历文本文件:

while ( (read=channel.read(byteBuffer)) != -1 )
{
    for ( int i=0; i<read; i++ )
        //my code
    byteBuffer.clear( );
}

我的问题是在这种情况下如何读取 Unicode 字符。 Unicode 字符由 2 个字节(16 位)组成,所以我认为 bArray[i] 包含第一个(更高的)8 位,随后的 8 位是该字符的第二部分。因此,例如,如果我需要找出这个字符:“#”当前是否在索引 i 和 i + 1 上,我可以这样做吗? (“#”二进制表示:0010 0011):

if (bArray[i] == (byte)10 && bArray[i+1] == (byte) 11)

感谢回复

【问题讨论】:

  • 你到底想做什么?为什么要读取这么低级别的文本文件?你甚至知道你正在阅读的文件的编码吗?
  • 如果“#”是0010 0011,你不应该只检查bArray[i] == 0x0bArray[i+1] == 0x23吗? Unicode 是两个字节,由于“#”是标准 ASCII 字符集的一部分,它在高字节中没有设置任何位,所以它的表示是0000 0000 0010 0011
  • @jonhopkins 实际上,由于 java 没有二进制表示,所以它应该分别是 0x00x23
  • @Jeff 很公平。我刚刚离开提供的示例。我之前没有在 Java 中使用过字节

标签: java byte


【解决方案1】:

简单的答案是您不应将文本数据视为字节流。具体而言,这意味着:不要使用ByteBuffer

使用InputStreamReader,它知道如何使用给定的编码来解释字节序列。

【讨论】:

  • +1。如果您想读取字符,请使用Reader,它知道使用哪个Charset 在字节和字符之间进行转换。
  • 问题是这个文本文件的读取速度必须非常快,如果我读取的文件级别那么低,我可以跳过一些字符,提高效率...
  • @Husky 你对代码进行了基准测试,发现InputStreamReader 太慢了吗?我严重怀疑这会是一个瓶颈。
  • 对于 Unicode 变体:“UTF-8”、“UTF-16LE”、“UTF-16BE”。 Unicode 将字符很好地编入 3 字节范围内。 UTF-8 是多字节,UTF-16 是 2 字节,部分字符不完整。
  • 这是一个 5 年前的基准。从那时起,Java 和 JVM 发生了很大变化。我是认真的:首先做简单、明智的事情,然后测量 (1) 如果您的程序太慢,然后再测量 (2) 如果最大的加速将来自避免 InputStreamReader。如果不是过早的优化,我看不出这是什么。如果您需要任何比 ASCII 更高级的编码,99% 以上的情况下,滚动您自己的实现是没有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多