BOM有りBOMなしのテキスト出力する OutputStreamWriter のサンプルコード

2020年9月18日金曜日

技術的備忘録 汎用ソースコード&ツール

t f B! P L


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有無のファイル出力も簡単だ。

このサンプルがお役に立てば幸いだ。


shift-jis と utf-8 の混在問題に関する記事(リンクリスト)に戻る


このブログを検索

Translate

人気の投稿

自己紹介

自分の写真
オッサンです。実務経験は Windows環境にて C#,VB.NET ,SQL Server T-SQL,Oracle PL/SQL,PostgreSQL,MariaDB。昔はDelphi,C,C++ など。 趣味はUbuntu,PHP,PostgreSQL,MariaDBかな ?基本無料のやつ。

QooQ