shift-jis と utf-8 の混在問題に関する記事(リンクリスト)に戻る
この記事は情技師(ITエンジニア)向けの記事です。
Java8 の OutputStreamWriter で BOM有り・BOMなしの utf テキストファイルを作成するサンプルコードをここに載せる。
以前書いた C# の StreamWriter のロジックと同じである。
この手のサンプルコードは検索すると沢山出てくるので、必ずしもこのコードでなくても良いと思う。
好きなサンプルコードを探すと良い。
以下が全サンプルコードである。
package WriteBOM;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
public class WriteBOM {
private static final String PATH = "C:\Users\username\OneDrive\eclipse-workspace\WriteBOM\run";
private static final String UTF8 = "UTF-8";
private static final String UTF16LE = "UTF-16LE";
private static final String UTF16BE = "UTF-16BE";
private static final String UTF32LE = "UTF-32LE";
private static final String UTF32BE = "UTF-32BE";
private static final String SHIFTJIS = "MS932";
private static final byte[] BOM_UTF8 = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
private static final byte[] BOM_UTF16Little = { (byte) 0xFF, (byte) 0xFE };
private static final byte[] BOM_UTF16Big = { (byte) 0xFE, (byte) 0xFF };
private static final byte[] BOM_UTF32Little = { (byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00 };
private static final byte[] BOM_UTF32Big = { (byte) 0x00, (byte) 0x00, (byte) 0xFE, (byte) 0xFF };
public static void main(String[] args) throws FileNotFoundException, IOException {
// Setting command parameters
String fileName;
if (args.length < 1)
{
fileName = "newFile.txt";
}
else
{
fileName = args[0];
}
String inputEncodingName;
if (args.length < 2)
{
inputEncodingName = UTF8;
}
else
{
inputEncodingName = args[1];
}
boolean existBOM;
if (args.length < 3)
{
existBOM = true;
}
else
{
if (args[2].toUpperCase().equals("FALSE"))
{
existBOM = false;
}
else
{
existBOM = true;
}
}
String text;
if(args.length < 4)
{
text = "ABCDE.12345.!#$%.あいうえお.アイウエオ.アイウエオ.日本漢字,欄廊俠俱.China产乡.Taiwan說姊.Korea희편";
}
else
{
text = args[3];
}
String fullPathName = PATH + "\" + fileName;
//Create file.
File file = new File(fullPathName);
try(FileOutputStream fos = new FileOutputStream(file))
{
//Write BOM.
if(existBOM)
{
byte[] bom = null;
switch(inputEncodingName)
{
case UTF8:
bom = BOM_UTF8;
break;
case UTF16LE:
bom = BOM_UTF16Little;
break;
case UTF16BE:
bom = BOM_UTF16Big;
break;
case UTF32LE:
bom = BOM_UTF32Little;
break;
case UTF32BE:
bom = BOM_UTF32Big;
break;
case SHIFTJIS:
bom = null;
break;
default:
bom = null;
}
if(bom != null)
{
fos.write(bom);
}
}
// Write Content.
try(BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos,Charset.forName(inputEncodingName))))
{
bw.write(text);
}
}
}
}
「コンソールアプリケーション」なので、コマンドプロンプトからこのコマンドを使用する。
コマンド引数は、「ファイル名」「エンコーディング名」「BOMの有無指定」「出力文字列」だ。
java <クラス名> <ファイル名> <エンコーディング名> <BOMの有無指定> <出力文字列>
全て省略可能である。
省略した場合は以下の値になる。
<ファイル名> "newFile.txt"
<エンコーディング名> "utf-8"
<BOMの有無指定> 有り
<出力文字列> "ABCDE.12345.!#$%.あいうえお.アイウエオ.アイウエオ.日本漢字,欄廊俠俱.China产乡.Taiwan說姊.Korea희편"
出力文字列には shift-jis では使用できない漢字を含めているので、これで shift-jis テキストを出力すると「日本漢字,」より後ろが文字化けする。
例えば、ファイル名「aaa.txt」で、shift-jis のテキストファイルを作成するなら以下のようにコマンド入力する。
java <クラス名> aaa.txt MS932
または
java <クラス名> aaa.txt MS932 false テスト文字列
<クラス名> = WriteBOM.WriteBOM
ファイル名「bbb.txt」で、BOM有り utf-8 のテキストファイルを作成するなら以下のようにコマンド入力する。
java <クラス名> bbb.txt UTF-8 true
または
java <クラス名> bbb.txt UTF-8 true テスト文字列
BOMなし utf-8 のテキストファイルなら、こうなる。
java <クラス名> bbb.txt UTF-8 false
または
java <クラス名> bbb.txt UTF-8 false テスト文字列
BOMを直接書き込む
予め BOM の byte 型配列を用意しておく。
private static final byte[] BOM_UTF8 = { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF };
private static final byte[] BOM_UTF16Little = { (byte) 0xFF, (byte) 0xFE };
private static final byte[] BOM_UTF16Big = { (byte) 0xFE, (byte) 0xFF };
private static final byte[] BOM_UTF32Little = { (byte) 0xFF, (byte) 0xFE, (byte) 0x00, (byte) 0x00 };
private static final byte[] BOM_UTF32Big = { (byte) 0x00, (byte) 0x00, (byte) 0xFE, (byte) 0xFF };
FileOutputStream でファイルを開いて、fos.write(bom); で、直接BOMを書き込む。
java 標準ライブラリはBOMに関する機能が無いので、手動でBOMを書き込む必要がある。
File file = new File(fullPathName);
try(FileOutputStream fos = new FileOutputStream(file))
{
//Write BOM.
if(existBOM)
{
byte[] bom = null;
switch(inputEncodingName)
{
case UTF8:
bom = BOM_UTF8;
break;
case UTF16LE:
bom = BOM_UTF16Little;
break;
case UTF16BE:
bom = BOM_UTF16Big;
break;
case UTF32LE:
bom = BOM_UTF32Little;
break;
case UTF32BE:
bom = BOM_UTF32Big;
break;
case SHIFTJIS:
bom = null;
break;
default:
bom = null;
}
if(bom != null)
{
fos.write(bom);
}
}
その後、FileOutputStream のインスタンスを OutputStreamWriter に渡してインスタンス化する。
BufferedWriter も同時にインスタンス化する。
このときエンコーディングを指定する。
try(BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos,Charset.forName(inputEncodingName))))
{
bw.write(text);
}
ごらんのように、OutputStreamWriter によるBOM有無のファイル出力も簡単だ。
このサンプルがお役に立てば幸いだ。