オープンソースである nkf を借用して,テキストファイルの文字コードを簡単に判別できます。バージョン 2.0.9 以降の nkf のライセンスは zlib/libpng License です (極めて良心的なライセンスです)。対応文字コードは次の通りです。
- Shift_JIS
- EUC-JP
- ISO-2022-JP
- UTF-8
- UTF-16LE
- UTF-16BE
nkf32.dll を用意し,実行ファイルと同じディレクトリに置く必要があります。nkf32.dll は Vector からダウンロードできます。元々の nkf とは異なるライセンスですので,配布条件を確認してください (とは言っても緩い条件です)。
- nkf.exe nkf32.dll Windows 用
- http://www.vector.co.jp/soft/win95/util/se295331.html
文字コードの判別を行うには,私が作った EncodingUtilities
クラスを利用してください。まずは使い方の見本から。
using System; using System.Text; class Program { static void Main() { string path = @"c:\works\hoge.txt"; // 文字コードを判別 Encoding enc = EncodingUtilities.DetectEncoding(path); // テキストエディタを作るならこうしとくといい if (enc == null || enc == Encoding.ASCII) { enc = Encoding.Default; } // 処理... } }
次のリンクからダウンロードできます。断りなく自由に使っていただいて結構です。
ソースコード: EncodingUtilities.cs
// EncodingUtilities.cs using System; using System.IO; using System.Text; /// <summary> /// エンコーディングを取り扱うユーティリティを提供します。 /// </summary> public static class EncodingUtilities { /// <summary> /// テキストファイルで使われている文字コードを判別し,対応する Encoding オブジェクトを返します。 /// </summary> /// <param name="path">テキストファイルへのパス。</param> /// <returns>Shift_JIS, EUC-JP, ISO-2022-JP, UTF-8, UTF-16, UTF-16BE, US-ASCII, null のいずれかが返ります。</returns> public static Encoding DetectEncoding(string path) { // -g: 自動判別の結果を出力する。 // -t: 何もしない。 SetNkfOption("-gt"); byte[] bytes; using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { bytes = new byte[fs.Length]; fs.Read(bytes, 0, bytes.Length); } unsafe { fixed (byte* pbs = bytes) { StringBuilder strBldr = new StringBuilder(1); NkfConvert(strBldr, (char*) pbs); } } int nEnc = NkfGetKanjiCode(); // US-ASCII も ISO-2022-JP と判別されるので,更に篩にかける。 if (nEnc == nJIS) { nEnc = nASCII; // US-ASCII と仮定する for (int i = 0; i < bytes.Length; i++) { if (bytes[i] == 0x1b) // ISO-2022-JP であれば ESC (0x1B) が含まれる { nEnc = nJIS; break; } } } switch (nEnc) { case nSJIS: return Encoding.GetEncoding("shift_jis"); case nEUC: return Encoding.GetEncoding("euc-jp"); case nJIS: return Encoding.GetEncoding("iso-2022-jp"); case nUTF8: return Encoding.GetEncoding("utf-8"); case nUTF16LE: return Encoding.GetEncoding("utf-16"); case nUTF16BE: return Encoding.GetEncoding("utf-16BE"); case nASCII: return Encoding.ASCII; default: return null; } } #region nkf functions [System.Runtime.InteropServices.DllImport("nkf32.dll")] static extern int SetNkfOption(string optStr); [System.Runtime.InteropServices.DllImport("nkf32.dll")] unsafe static extern void NkfConvert(StringBuilder outStr, char* inStr); [System.Runtime.InteropServices.DllImport("nkf32.dll")] static extern int NkfGetKanjiCode(); #endregion #region Fields // nSJIS, nEUC, nJIS, nUTF8, nUTF16LE, nUTF16BE の値は NkfGetKanjiCode() の戻り値に対応 const int nSJIS = 0; const int nEUC = 1; const int nJIS = 2; const int nUTF8 = 3; const int nUTF16LE = 4; const int nUTF16BE = 5; const int nASCII = 1001; #endregion }
「null 以外を返した」という結果は「文字コードを完全に特定できた」という意味を持つ訳ではありません。その点だけ注意してください。これは nkf の仕様に因ります。