如何建立编码字符的代码点?(How to establish the codepoint of en

2019-10-17 14:05发布

鉴于字节(表示字符)的流和流的编码,我将如何获得的字符的码点?

InputStreamReader r = new InputStreamReader(bla, Charset.forName("UTF-8"));
int whatIsThis = r.read(); 

什么是阅读()在上面的代码片段回来了? 它是Unicode的代码点?

Answer 1:

Reader.read()返回一个可以转换为一个值char或-1,如果没有更多的数据是可用的。

char是(隐含地)一个在UTF-16BE编码的16位的代码单元。 这种编码可以表示与单个基本多平面字符char 。 该补充范围是使用二维表示char序列。

所述Character类型包含用于翻译UTF-16代码单元,以Unicode编码点的方法:

需要两个A码点char旨意满足的isHighSurrogate和isLowSurrogate当在两个连续的值从一个传序列 。 所述提供codePointAt方法可用于从代码单元序列中提取的代码点。 有从代码点工作到UTF-16代码单元类似的方法。


一个码点流读取器的示例性实现:

import java.io.*;
public class CodePointReader implements Closeable {
  private final Reader charSource;
  private int codeUnit;

  public CodePointReader(Reader charSource) throws IOException {
    this.charSource = charSource;
    codeUnit = charSource.read();
  }

  public boolean hasNext() { return codeUnit != -1; }

  public int nextCodePoint() throws IOException {
    try {
      char high = (char) codeUnit;
      if (Character.isHighSurrogate(high)) {
        int next = charSource.read();
        if (next == -1) { throw new IOException("malformed character"); }
        char low = (char) next;
        if(!Character.isLowSurrogate(low)) {
          throw new IOException("malformed sequence");
        }
        return Character.toCodePoint(high, low);
      } else {
        return codeUnit;
      }
    } finally {
      codeUnit = charSource.read();
    }
  }

  public void close() throws IOException { charSource.close(); }
}


Answer 2:

它不读Unicode代码点,但UTF-16代码单元。 存在用于低于0xFFFF的代码点无差异,但上述0xFFFF的代码点由每2个代码单元表示。 这是因为你不能在16位具有上述0xFFFF的值。

所以在这种情况下:

byte[] a = {-16, -96, -128, -128}; //UTF-8 for