// 2018/10/27 17:57:37
*******************************************************************/
/// <summary>
/// BOMなしファイルのエンコード検査
/// </summary>
/// <param name="str_fname"></param>
/// <returns></returns>
private string inspectFileEncode( string str_fname ) //外部からコールのできるようにしておく
{
// ファイルのオープン
FileStream fs = File.OpenRead( str_fname );
// 初期化
int icount = 0; // UTF-8のバイト数
int icount2 = 0; // UTF-8でないバイト数
int icnt_s_jis1 = 0; // Shift-JISの2バイトコードと判定できる文字数
int ibuf_size = 4096 * 10;
byte[] bdata = new byte[ibuf_size];
int iread_size = 0; // バッファ読込みサイズ
int iread_count = 0; // バッファ読込み回数
//
do
{
// バッファの初期化
bdata.Initialize();
// ( offset は、0 でよい )
iread_size = fs.Read( bdata, 0, bdata.Length );
iread_count++;
// int i = 0;
for( int i = 0; i < iread_size; i++ )
{
// 0x00 があれば forループ
if( 0x00 == bdata[i] )
{
break;
}
// Shift-JISの2バイトコードの1バイト目判定(部分)
// ( 0xE0から0xFCまでは、UTF-8の3バイトコードの誤認識が多くなると考え省略 )
if( ( 0x81 <= bdata[i] ) && ( bdata[i] <= 0x9F ) ) // 1バイト目(部分判定)
{
// 配列あふれのチェック
if( iread_size <= ( i + 1 ) )
{
break; // チェックせず forループ終了
}
// バッファで分断されたUTF-8(2,3,4バイト目)と判定されるときはスキップ。
// バッファで分断されたUTF-8(2,3,4バイト目)となる確率のときはスキップ。
if( i < 3 )
{
if( 0x80 == ( 0xC0 & bdata[i] ) ) // Bug ?
{
continue;
}
}
// Shift-JISの2バイトコードの2バイト目判定
if( ( ( 0x40 <= bdata[i + 1] ) && ( bdata[i + 1] <= 0x7E ) ) ||
( ( 0x80 <= bdata[i + 1] ) && ( bdata[i + 1] <= 0xFC ) ) )
{
//
icnt_s_jis1++;
break;
}
} // ----------------------------------------------------
// UTF-8 の2バイト判定
// 1バイト目の上位3ビットが 110 であるか?
if( 0xC0 == ( 0xE0 & bdata[i] ) )
{
// 配列あふれのチェック
if( iread_size <= ( i + 1 ) )
{
break; // チェックせず forループ終了
}
// 2バイト目の上位2ビットが 10 であるか?
if( 0x80 == ( 0xC0 & bdata[i + 1] ) )
{
icount += 1;
i++;
}
else
{
icount2--;
break; //チェック中止
}
} // ----------------------------------------------------
// UTF-8 の3バイト判定
// 1バイト目の上位4ビットが 1110 であるか?
if( 0xE0 == ( 0xF0 & bdata[i] ) )
{
// 配列あふれのチェック
if( iread_size <= ( i + 2 ) )
{
break; // チェックせず forループ終了
}
// 2、3バイト目の上位2ビットが 10 であるか?
if( ( 0x80 == ( 0xC0 & bdata[i + 1] ) ) &&
( 0x80 == ( 0xC0 & bdata[i + 2] ) ) )
{
//
icount += 1;
i += 2;
}
else
{
icount2--;
break; //チェック中止
}
} // ----------------------------------------------------
// UTF-8 の4バイト判定
// 1バイト目の上位5ビットが 11110 であるか?
if( 0xF0 == ( 0xF8 & bdata[i] ) )
{
// 配列あふれのチェック
if( iread_size <= ( i + 3 ) )
{
break; // チェックせず forループ終了
}
// 2、3,4バイト目の上位2ビットが 10 であるか?
if( ( 0x80 == ( 0xC0 & bdata[i + 1] ) ) &&
( 0x80 == ( 0xC0 & bdata[i + 2] ) ) &&
( 0x80 == ( 0xC0 & bdata[i + 3] ) ) )
{
//
icount += 1;
i += 3;
}
else
{
icount2--;
break; //チェック中止
}
} // ----------------------------------------------------
} // for i
if( 0 < icnt_s_jis1 )
{
break; // Shift-JISと判定 ANSIとしておく
}
if( icount2 < 0 )
{
break; // ANSIとしておく
}
} while( iread_size == bdata.Length ); // 読み出しが、バッファ未満なら終了。
// ファイルクローズ
fs.Close();
// エンコード初期設定
string encode = CS_Define.ENCODE_UNKNOW;
// エンコード決定
if( 0 < icnt_s_jis1 ) // Shift-JISと判定される文字がある。
{
encode = CS_Define.ENCODE_ANSI;
}
else if( 0 < icount ) // UTF-8と判定される文字がある。
{
if( icount2 < 0 ) // 不完全な UTF-8の2,3,4バイトコードがある。
{
encode = CS_Define.ENCODE_ANSI;
}
else
{
// encode = CS_Define.ENCODE_UTF8;
encode = CS_Define.ENCODE_UTF8_WITHOUT_BOM;
}
}
else
{
// デフォルトをANSIとするか、UTF-8とするか、設定ダイアログで変更できるようにする。
encode = CS_Define.ENCODE_ANSI;
}
return encode;
}
//////////////////////