Java NIO2 UnmappableCharacterException
English follows Japanese.
- 以下のようにファイルの出力をNIOからNIO2に書き換えた場合、出力時の値によっては動作が違ってきます。
「Pokémon」を文字コードをsjisを指定してファイル出力する処理をNIOとNIO2で記述してみました。
- NIOの場合は、正常終了するのですが、出力したファイルは「Pock?mon」となっています。
- NIO2の場合は、UnmappableCharacterExceptionになります。
そもそも文字コードとして正しくない値を出力しているのが問題ではあるのですが、リファクタリングしたことで動作が違ってくるのは、、、
- When you refactor codes from Java NIO to NIO2 like below, you will have different results.
I implemented the function which writes the value [Pokémon] to the file with sjis Charset.
- When using NIO the method ended without Exception, but the result is Pock?mon.
- When using NIO2 the method ended with UnmappableCharacterException.
Basically it is wrong using mismatched Charset, but I did not expect to see the different result... :-(
- Sample.java
package com.sample; import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class Sample { public static void main(String... args) throws IOException { Sample sample = new Sample(); sample.writeNIO(); sample.writeNIO2(); } void writeNIO() { String val = "Pockémon"; try (BufferedWriter writer = new BufferedWriter( new OutputStreamWriter(new FileOutputStream("/Users/tomo/NIO.txt"), Charset.forName("sjis")))) { writer.write(val); } catch (IOException e) { e.printStackTrace(); } } void writeNIO2() throws IOException { String val = "Pockémon"; Path path = Paths.get("/Users", "tomo", "NIO2.txt"); try (BufferedWriter writer = Files.newBufferedWriter(path, Charset.forName("sjis"));) { writer.write(val); } } }
- SampleTest.java
package com.sample; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.nio.charset.UnmappableCharacterException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import org.junit.Before; import org.junit.Test; public class SampleTest { Sample sample; @Before public void setUp() throws Exception { sample = new Sample(); } @Test public void testWriteNIO() { sample.writeNIO(); Path path = Paths.get("/Users", "tomo", "NIO.txt"); boolean exists = Files.exists(path); assertTrue(exists); } @Test(expected = UnmappableCharacterException.class) public void testWriteNIO2() throws IOException { sample.writeNIO2(); } }
The code is here gist.github.com