狠狠撸

狠狠撸Share a Scribd company logo
nioで作ったBufferedWriterに
変えたら例外になった
2016-2-13
第十四回 #渋谷java
自己紹介
島本 多可子(@chibochibo03)
株式会社ビズリーチ CTO室
普段はScalaを書いてます
GitBucketやってます
https://github.com/gitbucket/gitbucket
直近の著書です →
ある日
変更前
普通に生成していた
val charset: String = …
new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(new File("...")), charset
)
)
変更後
深く考えずnioのFiles.newBufferedWriterに変更
val charset: String = …
Files.newBufferedWriter(
Paths.get("..."), Charset.forName(charset)
)
例外発生
Σ( ̄Д ̄;)なぬぅっ!!
java.nio.charset.UnmappableCharacterException
スタックトレース
Failed to import XML. java.nio.charset.UnmappableCharacterException: Input
length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:282)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:285)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.BufferedWriter.close(BufferedWriter.java:265)
(?へ`;ウーム
(━_━)ゝ???
?? (?Д?;)!!
どうやら化ける文字に対する扱いが异なるようだ
こんなテストコードを用意
// 通常版
def normal() = {
val charset = "EUC_JP"
val data = "Java"+ "u3030" +"Scala"
IO(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("...")), charset))).
using { writer =>
IO {
writer.write(data)
writer.flush()
}
}
}
こんなテストコードを用意
// 通常版
def normal() = {
val charset = "EUC_JP"
val data = "Java"+ "u3030" +"Scala"
IO(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File("...")), charset))).
using { writer =>
IO {
writer.write(data)
writer.flush()
}
}
}
Javaで、EUC_JPで出力不可な文字
結果
// 変換できない文字は'?'に置換
Java?Scala
nioの場合
// nio版
def nio() = {
val charset = "EUC_JP"
val data = "Java"+ "u3030" +"Scala"
IO(Files.newBufferedWriter(Paths.get("..."), Charset.forName(charset))).using { writer =>
IO {
writer.write(data)
writer.flush()
}
}
}
結果
// 例外が発生し、出力もおかしなことに
JavaJava
(;¬д¬) ????
スタックトレース
Failed to import XML. java.nio.charset.UnmappableCharacterException: Input
length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:282)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:285)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.BufferedWriter.close(BufferedWriter.java:265)
StreamEncoder.implWrite
CharsetEncoder.encodeの結果次第
颁丑补谤蝉别迟贰苍肠辞诲别谤はどうやって决まる?
苍别飞叠耻蹿蹿别谤别诲奥谤颈迟别谤の场合
苍别飞叠耻蹿蹿别谤别诲奥谤颈迟别谤の场合
newBufferedWriterでたどり着く先
エンコードエラー時の動作は指定なし
=> CodingErrorAction.REPORT
CodingErrorAction.REPORT
エラーが発生した時点で処理を中断し、エラーを報告する
従来の场合
従来でたどり着く先
不正入力エラー、マッピング不可エラー時の動
作指定あり
CodingErrorAction.REPLACE
エラーが発生した入力文字を指定した文字に置換して出力し、処理を継続する
デフォルトは「?」
設定されている置換文字列はreplacement メソッドで取得可能
(o???)o ??――?
これが答え
CharsetEncoder.encode - 一部抜粋
苍别飞叠耻蹿蹿别谤别诲奥谤颈迟别谤の场合
従来の场合
まとめ
エンコードエラー時、置換文字による代替で処理を継続するか、エラーを通知してほしい
か、時と場合による
特に外部からのデータフィードの場合は、変な文字が紛れ込む
すぐに対応してもらえないことも???
nioのFiles.newBufferedWriterはエンコードエラー時に例外を投げるので注意

More Related Content

苍颈辞で作った叠耻蹿蹿别谤别诲奥谤颈迟别谤に変えたら例外になった