给定一个字节流(代表字符)和该流的编码,我如何获得字符的代码点?

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


上面的代码段中的read()返回了什么?它是unicode代码点吗?

最佳答案

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

char是(隐式)UTF-16BE编码中的16位代码单元。此编码可以用单个char表示基本的多语言平面字符。 supplementary range用两个char序列表示。

Character类型包含用于将UTF-16代码单元转换为Unicode代码点的方法:

当您从isHighSurrogate传递两个连续值时,需要两个char的代码点将满足isLowSurrogatesequencecodePointAt方法可用于从代码单元序列中提取代码点。从代码点到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(); }
}

10-05 21:35