オープンソースである 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 の仕様に因ります。