Help us understand the problem. What is going on with this article?

書くときにも発生する MalformedInputException

自分が書いた Java プログラムが以下のエラーを出力した。

Caused by: java.nio.charset.MalformedInputException: Input length = 1
    at java.base/java.nio.charset.CoderResult.throwException(CoderResult.java:274)
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:306)
    at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
    at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
    at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:211)
    at java.base/java.io.BufferedWriter.flushBuffer(BufferedWriter.java:120)
    at java.base/java.io.BufferedWriter.flush(BufferedWriter.java:256)
以下アプリケーションコードのスタックトレース部分を省略

文字エンコーディングに関する問題であることはすぐわかるが、次のアプリケーションコードの該当箇所を見ても理由が思い当たらない。

File file = ...;
try (BufferedWriter writer = java.nio.file.Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
    String s = ...;
    writer.write(s);
    writer.flush(); // ここでエラーが出るので直前の write の引数が怪しいが...
}

こういうときは文字列の s をダンプして s の中身を調べるのが常套手段。

System.err.println("[" + s + "]");

とすると、以下のように表示された。? は何だろう、文字化けか?
そもそも、System.err#println だとエラーが出ないのか...

[?]

ここで サロゲートペア にすぐ気づかなかったのは迂闊であった。
以下のコードで s の各文字を調べると、 High. が表示された。最初のエラーの原因はこれだ。

for (char c : s.toCharArray()) {
    if (Character.isHighSurrogate(c)) {
        System.err.println("High.");
    }
    if (Character.isLowSurrogate(c)) {
        System.err.println("Low.");
    }
}

2020年現在、サロゲートペアをきちんと考慮した Java プログラミングは、常識のお作法であろうか。

daylife
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした