外部ファイルの文字コードの自動判定(秀丸アルゴ)

秀丸の設定に則った外部ファイルのエンコード判定 (秀丸エディタ 8.90以降)

秀丸が対象の外部テキストを「これから」初めて「あなたの秀丸エディタ」で読み込んだと仮定すると、
秀丸は、対象のファイルをどのエンコードと判断するだろうか、その結果を取得する関数です。

ポイントは「初めて」と「あなたの秀丸エディタ」の設定で読み込んだ場合、ということになります。
どのPCでも同じとなる汎用的な結果が返ってくる機能ではありません。

設定は、秀丸より「その他」⇒「動作環境」⇒「ファイル」⇒「エンコード1」で主に設定されています。
この優先順位にしたがって判定され、また、チェックが付いていないエンコード値は、この関数では「取り扱わないもの」とされます。
PICTURE

このように、あくまでも「あなたの秀丸エディタの設定」と一致したエンコード情報が欲しい場合に、このメソッドを利用します。

秀丸でファイルのエンコードを取得する(秀丸に設定されている内容に従う)

hm.File.GetEncoding( String filepath )

この返り値のオブジェクトには「MsCodePage」と「HmEncode」がプロパティとして存在します。
HmEncodeには、秀丸マクロの「encode」の解説書 の「encode」の項目に対応する値が格納されています(※)。
MsCodePageには、秀丸の独自のencode値を、Windows上での「コードページ」の番号へと置き換えたものです。

PyEncodingNameには、Pythonのファイル読み込み系や文字コードで良く利用される「文字コード名(例: utf-8 や cp032)が得られます。
  • ※秀丸の「encode」の値

    0  新規作成直後
    1  Shift-JIS
    2  Unicode(UTF-16)
    3  EUC
    4  JIS
    5  UTF-7
    6  UTF-8
    7  Unicode (UTF-16,Big-Endian)
    8  欧文
    9  簡体字中国語
    10 繁体字中国語
    11 韓国語
    12 韓国語(Johab)
    13 中央ヨーロッパ言語
    14 バルト語
    15 ギリシャ語
    16 キリル言語
    17 シンボル
    18 トルコ語
    19 ヘブライ語
    20 アラビア語
    21 タイ語
    22 ベトナム語
    23 Macintosh
    24 OEM/DOS
    25 その他
    26 バイナリモード
    27 Unicode(UTF-32) (V8.00以降)
    28 Unicode(UTF-32,Big-Endian) (V8.00以降)
    
  • 使用例

    #PY= loaddll( hidemarudir + @"\hmPY.dll" );
    
    #_ = dllfuncw( #PY, "DoString", R"PY(
    import clr
    import sys
    
    try:
        target_filepath = r"D:\test\test.txt"
    
        # GetEncoding で、「HmEncode」と「MsCodePage」と「PyEncodingName」をプロパティとして持つオブジェクトが返ってくる。
        encoding = hm.File.GetEncoding(target_filepath)
    
        hm.debuginfo(encoding.HmEncode)
        hm.debuginfo(encoding.MsCodePage)
        hm.debuginfo(encoding.PyEncodingName) # Python のファイル系のエンコードとしてよく使用される文字列
    
        # MsCodePage にはコードページ番号が入っているため、、.NET のSystem.Text.Encodingでテキストエンコードオブジェクトに逆引きできる。
        text_encoding = System.Text.Encoding.GetEncoding(encoding.MsCodePage)
        hm.debuginfo(text_encoding)
    
        # それを使えば、.NET の様々な読み取り系関数で利用することができる。
        text = System.IO.File.ReadAllText(target_filepath, text_encoding)
        hm.debuginfo(text)
    
    except IOError as e:
        hm.debuginfo("IOError")
    except:
        hm.debuginfo("Error")
    
    
    
    )PY");
    
    freedll( #PY );
                

対象のパスにファイルを置いたり、ファイル名を変更したり、ファイルのエンコードを変更するなどして、
いろいろと挙動を確認してみましょう。

特に、「その他」⇒「動作環境」⇒「ファイル」⇒「エンコード1」 で判定対象となっていないエンコードの場合に、
強引にどれかに秀丸が当てはめようとしてしまうため、判定ミスが発生します。

よって、この関数が使えるには、「対象のディレクトリには、自分自身が使っている秀丸なら一発でエンコードが正しく判断可能」でありという
「そういったファイル群に対してのみ自動で振り分けて処理をする」といった限られたシーンで利用することとなるでしょう。

秀丸の設定に則って外部ファイルを読み込む (秀丸エディタ 8.90以降)

上述では、秀丸の機能を使って外部ファイルのエンコードを判定しましました。
該当のソースでは、.NET Frameworkのクラスを利用して、テキストを読み込んでいますが、
秀丸から提供されている関数を利用したメソッドも提供しています。

このように、あくまでも「あなたの秀丸エディタの設定」と一致したテキスト読み込み結果が欲しい場合に、このメソッドを利用します。

秀丸でファイルのエンコードを判断し(この時、秀丸に設定されている内容に依存する)、
その判断結果に基づいて、ファイルのテキスト内容を取得する。

マクロ中でもマクロ中以外でも、常時取得することが出来ます。

IHidemaruStreamReader Hm.File.Open( String filepath, [int hm_encode] )
  • IHidemaruStreamReader

    public interface IHidemaruStreamReader : IDisposable
    {
        IEncoding Encoding { get; }
        string FilePath { get; }
        void Close();
        string Read();
    }
    
    

    となっています。

  • 使用例

    #PY= loaddll( hidemarudir + @"\hmPY.dll" );
    
    #_ = dllfuncw( #PY, "DoString", R"PY(
    import clr
    import sys
    
    try:
        target_filepath = r"D:\test\test.txt"
    
        # Open関数を利用することで、プロパティを持ったオブジェクトが返ってくる。
        # このオブジェクトは「Encoding」「FileName」のプロパティと、「Read()」「Close()」のメソッドを持つ。
        sr = hm.File.Open(target_filepath);
    
        hm.debuginfo(sr.FilePath)
    
        # 「Encoding」プロパティには、「HmEncode」と「MsCodePage」をプロパティとして持つオブジェクトが返ってくる。
        encoding = sr.Encoding;
        hm.debuginfo(encoding.HmEncode)
        hm.debuginfo(encoding.MsCodePage)
    
        text = sr.Read()
        hm.debuginfo(text)
    
        # ここでは明示的にクローズしているが、クローズし忘れても、sr が解放されれば、そのうち解放される。
        # リソースのハンドルが残り続けるといったことはない。
        sr.Close()
    
    except IOError as e:
        hm.debuginfo("IOError")
    except:
        hm.debuginfo("Error")
    
    
    )PY");
    
    freedll( #PY );
                
  • ファイルコードの指定

    秀丸の自動エンコード判定では、失敗する時、あるいは、事前にエンコードが決め打たれている場合には、
    エンコードを指定することが出来ます。
    とはいえ、エンコードが事前に分かっているのであれば、普通に .NET Frameworkのファイル読み込み系のクラスメソッドを利用したほうが良いでしょう。

    #PY= loaddll( hidemarudir + @"\hmPY.dll" );
    
    #_ = dllfuncw( #PY, "DoString", R"PY(
    import clr
    import sys
    
    try:
        target_filepath = r"D:\test\test.txt"
    
        # 強制的に 秀丸の「encode」を指定上書きすることが可能。
        # 「3」とは「EUC-JP」で、強制決め打ちして読み込み(前節の encode の一覧表を参照)。
        # 自動だと間違ってしまう場合に指定するのが良い。
        sr = hm.File.Open(target_filepath, 3)
        hm.debuginfo(sr.FilePath)
    
        # 「Encoding」プロパティには、「HmEncode」と「MsCodePage」をプロパティとして持つオブジェクトが返ってくる。
        encoding = sr.Encoding
        hm.debuginfo(encoding.HmEncode)
        hm.debuginfo(encoding.MsCodePage)
        encoding_name = System.Text.Encoding.GetEncoding(encoding.MsCodePage).EncodingName
        hm.debuginfo(encoding_name)
    
        text = sr.Read()
        hm.debuginfo(text)
    
        # ここでは明示的にクローズしているが、クローズし忘れても、sr が解放されれば、そのうち解放される。
        # リソースのハンドルが残り続けるといったことはない。
        sr.Close()
    
    except IOError as e:
        hm.debuginfo(e)
    
    
    )PY");
    
    freedll( #PY );