ファイル符号化(テキストストリーム符号化)を判定する方法


プログラムでは、テキストファイルはよく標準のASCIIコードテキストを記憶するために用いられます.例えば、英語、加減乗除等号などの演算記号です.テキストファイルは、GBKベースの簡体字中国語、GIG 5ベースの繁体字中国語などの他のASCII文字を格納するためにも使用され得る.これらの文字を保存するには、ファイルの符号化フォーマットを正しく指定する必要があります.これらの文書ファイルを読み込むには、自動的にファイルの符号化フォーマットを判定する必要がある場合があります.与えられた文字セットに従ってテキストファイルを格納する場合、ファイルの先頭の3バイトには符号化情報が格納されている可能性があるので、基本的な原理は、ファイルの前の3バイトを読めば、これらのバイトの値を判定し、その符号化フォーマットを知ることができるということです.実際には、プロジェクトが実行するプラットフォームが中国語オペレーティングシステムである場合、これらの文書ファイルがプロジェクト内で生成され、つまり、開発者はテキストの符号化フォーマットを制御できます.中国語のWindowsはデフォルトの符号化はGBKですので、UTF-8符号化フォーマットを判定するだけです.UTF−8符号化フォーマットのテキストファイルについては、その前の3バイトの値が−17、−69、−65であるため、UTF−8符号化フォーマットのコードセグメントかどうかを判定する.
 
 java.io.File f=new java.io.File("         ");
    try{
      java.io.InputStream ios=new java.io.FileInputStream(f);
      byte[] b=new byte[3];
      ios.read(b);
      ios.close();
      if(b[0]==-17&&b[1]==-69&&b[2]==-65)
         System.out.println(f.getName()+"   UTF-8");
      else System.out.println(f.getName()+"   GBK");
    }catch(Exception e){
       e.printStackTrace();
    }
 
 上記のコードは単にUTF-8フォーマットのコード化されたテキストファイルかどうかを判定します.項目が判定するテキストファイルのコードを制御できない場合(例えば、ユーザーがアップロードしたHTML、XMLなどのテキスト)、既存のオープンソース項目を採用できます.cpdetector、その所在地はhttp://cpdetector.sourceforge.net/です.そのクラスはとても小さくて、500 Kぐらいしかないです.このクラスを利用してテキストファイルのコードを判定します. 
 
 
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

import info.monitorenter.cpdetector.io.ASCIIDetector;
import info.monitorenter.cpdetector.io.CodepageDetectorProxy;
import info.monitorenter.cpdetector.io.JChardetFacade;
import info.monitorenter.cpdetector.io.ParsingDetector;
import info.monitorenter.cpdetector.io.UnicodeDetector;


public class cpdetectorTest {

	public static void main(String[] args){
		/*------------------------------------------------------------------------  
		  detector    ,                     。  
		  cpDetector             ,              add    
		     , ParsingDetector、 JChardetFacade、ASCIIDetector、UnicodeDetector。    
		  detector  “            ,       ”           
		       。  
		--------------------------------------------------------------------------*/  
		CodepageDetectorProxy detector =   CodepageDetectorProxy.getInstance();   
		/*-------------------------------------------------------------------------  
		  ParsingDetector     HTML、XML          ,            
		                 , false   。  
		---------------------------------------------------------------------------*/  
		detector.add(new ParsingDetector(false));    
		/*--------------------------------------------------------------------------  
		  JChardetFacade    Mozilla     JChardet,               
		    。  ,                     ,       ,    
		          ,     ASCIIDetector、UnicodeDetector 。  
		---------------------------------------------------------------------------*/    
		detector.add(JChardetFacade.getInstance());   
		//ASCIIDetector  ASCII       
		detector.add(ASCIIDetector.getInstance());   
		//UnicodeDetector  Unicode          
		detector.add(UnicodeDetector.getInstance());
		java.nio.charset.Charset charset = null;   
		File f=new File("D:\\test\\File\\PDFToFlex.mxml.txt");   
		try {   
		      charset = detector.detectCodepage(new BufferedInputStream(new FileInputStream(f)),100);   
		} catch (Exception ex) {ex.printStackTrace();}   
		if(charset!=null){   
		     System.out.println(f.getName()+"   :"+charset.name());   
		}else{  
		    System.out.println(f.getName()+"  ");  
		}
	}
}
 
 
上のコードのdetectorは、ファイルのコードを検出するだけでなく、入力されたテキストストリームのコードを検出することもできます. 
 charset=detector.detectCodepage(        ,            );
      
上のバイト数は、プログラマによって指定され、バイト数が多ければ多いほど、判定が正確になり、当然時間も長くかかります.バイト数の指定は、テキストストリームの最大長を超えてはいけません. 
  ファイルコードを判定する具体的なアプリケーション例: 
  属性ファイル(.properties)はJavaプログラムの一般的なテキスト記憶方式であり、STRUTSフレームは属性ファイル記憶プログラムの文字列リソースを利用することである.その内容は以下の通りです. 
   #    
      =   
   
            :     
  FileInputStream ios=new FileInputStream("     ");
  Properties prop=new Properties();
  prop.load(ios);
  ios.close();  
  java.io.Proptiesのロードを利用して属性ファイルを読み込むのは便利ですが、属性ファイルに中国語があると、読み込むと文字化けが発生します.この理由は、ロード方法がバイトストリームを使ってテキストを読み込むために、読み込んだ後にバイトストリームを文字列として符号化する必要があります.これは「iso-859-1」を使用しています.この文字セットはASCIIコードの文字セットで、中国語コードに対応していません.この場合は、明示的なトランスコードを使用する必要があります. 
   String value=prop.getProperty("   ");
   String encValue=new String(value.getBytes("iso-8859-1"),"         "); 
  上のコードでは、プロパティファイルの実際のコードを上の方法で取得することができます.もちろん、このような属性ファイルはプロジェクト内部のもので、例えばWindows内定のGBKを採用すると約束した場合、直接に「gbk」を利用してトランスコードしてもいいです.もしUTF-8を採用すると約束したら、「UTF-8」を使って直接トランスコードしてもいいです.柔軟にしたいなら、自動的にコードを探知することができます.上で紹介した方法で属性ファイルのコードを測定することができます.