Java の BOMInputStream による shift-jis と UTF の読み分け処理のサンプルコード

2020年10月30日金曜日

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

t f B! P L


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


Java の Apache Commons の BOMInputStream を用いた、shift-jis と BOM有りの UTF_8, UTF_16LE, UTF_16BE, UTF_32LE, UTF_32BE を読み分ける処理のサンプルコードを掲載する。

BOMなし UTF には対応していない。BOMなしは shift-jis と見なす。

 

コマンドラインからJavaとコマンドクラスとファイル名を入力すると、文字エンコーディング名とテキストファイルの内容を表示する。

 

Apache Commons IO は以下からダウンロードして組み込む。

https://commons.apache.org/proper/commons-io/

 

 

今回は Apache Commons の BOMInputStream を使用している為、CLASSPATH で org.apache.commons.io の置かれているパスを指定する必要がある。

今回は commons-io-2.8.0.jar を使用した。

 

jar や CLASSPATH の参照設定は java が使える人なら分かるだろうし、開発環境によっても違うだろうから説明しない。

 

以下にサンプルコードを全てを掲載する。

package comio1;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

import org.apache.commons.io.ByteOrderMark;
import org.apache.commons.io.input.BOMInputStream;;

public class ReadTextBOM {

	private static final String SHIFTJIS = "MS932";

	public static void main(String[] args) {
		//
		if(args.length < 1) return;
		
		String filename = args[0];
		
		try(BOMInputStream bis = new BOMInputStream(
				new FileInputStream(new File(filename))
					,true
					,ByteOrderMark.UTF_8
					,ByteOrderMark.UTF_16LE
					,ByteOrderMark.UTF_16BE
					,ByteOrderMark.UTF_32LE
					,ByteOrderMark.UTF_32BE))
		{
			Charset charSetName;
			if(bis.hasBOM()) {
				charSetName = Charset.forName(bis.getBOMCharsetName());
				ByteOrderMark bom = bis.getBOM();
				byte[] buff = new byte[4];
				bis.read(buff, 0, bom.length());
			}
			else
				charSetName = Charset.forName(SHIFTJIS);
			
			System.out.println(charSetName.toString());
			
			try(BufferedReader br = new BufferedReader(
					new InputStreamReader(bis, charSetName)))
			{
				
				String text;
				while((text = br.readLine()) != null)
				{
					System.out.println(text);
				}
			};
			
		} catch (FileNotFoundException e) {
			System.out.println("FileNotFoundException " + e.getMessage());
			//e.printStackTrace();
		} catch (IOException e) {
			System.out.println("IOException " + e.getMessage());
			//e.printStackTrace();
		}

	}

}

 

コード解説

処理内容は以前紹介した InputStreamReader の処理と同じだ。

FileInputStream インスタンスと、InputStreamReader インスタンスの間に、BOMInputStream インスタンスが挟まる形になる。

最初の try() で、BOMInputStream インスタンスを取得して、そのインスタンスの hasBOM() でBOMの判別を行う。

取得したBOMの長さだけ read() でBOMを読み飛ばし、次の try() で、取得したBOMのキャラクターセット InputStreamReader インスタンスと、BufferedReader のインスタンスを得て、テキストファイルの内容を readLine() で取得する。

 

BOMInputStream は、C# で紹介した StreamReader と違い、BOM を自動では読み飛ばしてくれない為、手動で読まなければならない。

このぐらい自動でやって欲しいところだ。

 

 

外部クラスライブラリだが、 Apache Commons なので、標準に近い。

コードも短く、解説も簡単になる。

 

以前書いた書き方は、外部クラスライブラリを使用しないで Java の標準ライブラリだけで書いたコードサンプルだ。

しかし、通常は汎用的なクラスライブラリを導入して使用すると思う。

 

 

Java プログラマーだと、こちらが標準的な書き方に近いと思う。

 

 

既に知っているかも知れないが、お役に立てば幸いだ。

 

BOMの書き込み処理

 

Apache Commons は、BOMInputStream が存在するが、BOMOutputStream は存在しない。

BOMを書き込む機能というものが、そもそも用意されていない。

私は Java 開発は本業ではないので、あまり詳しくないが、Java 標準クラスライブラリはBOMには未対応であり、Apache Commons もBOM書き込み機能は用意していない。

Java による 手動BOM書き込み処理のサンプルは以前紹介した。

 

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

https://www.wake-mob.jp/2020/09/bombom-outputstreamwriter.html

 

BOMの有無を識別し、UTFを識別して Java の Files で読み書きするサンプルコード

https://www.wake-mob.jp/2020/10/bomutf-java-files.html

 

簡単なので「自分で手作りしてくれ」という事なのかも知れない。

 

 


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