DOBON.NETプログラミング道掲示板
(現在 過去ログ1 を表示中)

HOME HELP 新規作成 新着記事 トピック表示 発言ランク ファイル一覧 検索 過去ログ

[ 最新記事及び返信フォームをトピックトップへ ]

■32926 / inTopicNo.1)  IO.StreamReaderでエンコードを自動判別して開く
  
□投稿者/ レミリア 一般人(1回)-(2015/04/29(Wed) 19:55:47)
  • アイコン環境/言語:[Windows8.1 32bit/VS Community 2013/Visual Basic] 
    分類:[.NET] 

    VBなのですが、
    StreamReaderでテキストを開きTextBoxで表示するコードなんですが、
    メモ帳では開けるものが文字化けしてしまいます。

    どんな文字コードが来るかわからないので、エンコードを自動判別して開く実装をしたいのですが、
    どうすればいいでしょうか?
    Dim sr As IO.StreamReader = New IO.StreamReader(filename,True)
    という構文はダメでした。また、dobon.netに載っている、バイト列を渡すとエンコードを返す関数を使っても変わりませんでした。

引用返信 削除キー/
■32927 / inTopicNo.2)  Re[1]: IO.StreamReaderでエンコードを自動判別して開く
□投稿者/ Azulean 大御所(441回)-(2015/04/29(Wed) 20:24:04)
  • アイコン一般的に、エンコードの判定は、特定の限定条件がついていない場合、非常に手間のかかる処理です。
    .NET Framework の StreamReader に(BOM による判別を除いて)自動判別機能はついていませんので、たいていは別途ライブラリを利用するか、世の中に出回っているサンプルソースを元に実装を組み込むのだと思います。

    No32926に返信(レミリアさんの記事)
    > どんな文字コードが来るかわからないので、エンコードを自動判別して開く実装をしたいのですが、
    > どうすればいいでしょうか?

    BOM のある Unicode テキストファイルと、ある特定のエンコードのファイルという風に限られるのであれば、その特定のエンコードの Encoding を渡しつつ、detectEncodingFromByteOrderMarks を True にしておくとよいでしょう。
    https://msdn.microsoft.com/ja-jp/library/ms143457(v=vs.110).aspx


    この限定条件では厳しい場合、「一般的にこれを使う」という風に固まったものはないので、自分の要求に照らしてふさわしいサンプルコード、ライブラリを探すことが必要になります。
    DOBON.NET さんも1つの情報として以下のコンテンツを公開されていますのでご参考までに。
    http://dobon.net/vb/dotnet/string/detectcode.html
引用返信 削除キー/
■32928 / inTopicNo.3)  Re[2]: IO.StreamReaderでエンコードを自動判別して開く
□投稿者/ レミリア 一般人(2回)-(2015/04/29(Wed) 23:25:24)
  • アイコン回答ありがとうございます。
    提示されたページのGetCode関数を使ったのですが、今度はTextBoxが
    空になります(streamreaderコンストラクタの第二引数にGetCodeの結果を渡してますg
    ブレークポイントで調べたところ、
    TextBox1.Text = sr.ReadToEnd()
    という構文が実行されませんでした(ちなみにDragdropイベントハンドラ内部での処理なのですが)
    No32927に返信(Azuleanさんの記事)
    > 一般的に、エンコードの判定は、特定の限定条件がついていない場合、非常に手間のかかる処理です。
    > .NET Framework の StreamReader に(BOM による判別を除いて)自動判別機能はついていませんので、たいていは別途ライブラリを利用するか、世の中に出回っているサンプルソースを元に実装を組み込むのだと思います。
    >
    > ■No32926に返信(レミリアさんの記事)
    >>どんな文字コードが来るかわからないので、エンコードを自動判別して開く実装をしたいのですが、
    >>どうすればいいでしょうか?
    >
    > BOM のある Unicode テキストファイルと、ある特定のエンコードのファイルという風に限られるのであれば、その特定のエンコードの Encoding を渡しつつ、detectEncodingFromByteOrderMarks を True にしておくとよいでしょう。
    > https://msdn.microsoft.com/ja-jp/library/ms143457(v=vs.110).aspx
    >
    >
    > この限定条件では厳しい場合、「一般的にこれを使う」という風に固まったものはないので、自分の要求に照らしてふさわしいサンプルコード、ライブラリを探すことが必要になります。
    > DOBON.NET さんも1つの情報として以下のコンテンツを公開されていますのでご参考までに。
    > http://dobon.net/vb/dotnet/string/detectcode.html
引用返信 削除キー/
■32929 / inTopicNo.4)  Re[3]: IO.StreamReaderでエンコードを自動判別して開く
□投稿者/ Azulean 大御所(442回)-(2015/04/29(Wed) 23:36:15)
  • アイコン2015/04/29(Wed) 23:40:05 編集(投稿者)

    No32928に返信(レミリアさんの記事)
    > 提示されたページのGetCode関数を使ったのですが、今度はTextBoxが
    > 空になります(streamreaderコンストラクタの第二引数にGetCodeの結果を渡してますg

    GetCode の戻り値がどうなっているか調べてください。

    > TextBox1.Text = sr.ReadToEnd()
    > という構文が実行されませんでした(ちなみにDragdropイベントハンドラ内部での処理なのですが)

    DragDrop イベントで例外が発生した場合、何事もなかったかのように処理が中断されて、デバッガは例外で止まりません。
    必要に応じて、デバッグメニューの例外から、「スローされるとき」に止めるようにしたら何が起きているかわかるかもしれません。
    (常に ON にすると気にしないで良いものまで止まることがあります)


    // 予想としては、GetCode の失敗(Nothing)か、GetCode に渡すためのバイト列を読むために、ファイルの現在位置(Position)が末尾になってしまっているか。
引用返信 削除キー/
■32930 / inTopicNo.5)  Re[1]: IO.StreamReaderでエンコードを自動判別して開く
□投稿者/ 魔界の仮面弁士 大御所(958回)-(2015/04/30(Thu) 11:04:54)
  • アイコン2015/04/30(Thu) 11:10:21 編集(投稿者)

    No32926に返信(レミリアさんの記事)
    > StreamReaderでテキストを開きTextBoxで表示するコードなんですが、
    > メモ帳では開けるものが文字化けしてしまいます。

    地域設定や OS バージョンによって、メモ帳がサポートしている
    文字コードは変わりますが、現行の日本語 OS に限って言えば、
    ・ANSI (US-ASCII ではない)
    ・UTF-8 (BOM はあっても無くても可)
    ・Unicode (リトルエンディアンなUTF-16、BOM はあっても無くても可)
    ・Unicode big endian (ビッグエンディアンなUTF-16、BOM無しには非対応)
    となっているようですね。


    > どんな文字コードが来るかわからないので、

    ある程度の絞込みは必要だと思います。
    まぁ、それでも機械的に判断できる保証は無いですが…。


    たとえば E0 E8 というバイナリがあったとします。
    そして、そのデータで使われている文字コードが、
    Shift_JIS か EUC-JP の二択だったと仮定します。

    E0 E8 は、EUC-JP なら、こはく色の「琥」の字にデコードされ、
    Shift_JIS では、コーヒーの「琲」の字にデコードされます。

    コーヒーの「琲」を EUC-JP でエンコードすると、E0 EA ですし、
    E0 EA を Shift_JIS でデコードすると、玉にきずの「瑕」の字です。

    ……これでは判断のしようが無いですよね。
    どちらにも解釈できてしまいます。


    なお、00〜7F までの 7bit 範囲なデータだけで構成されていた場合に、
    それを ASCII として解釈する実装も見受けますが、必ずしも
    この判断も正確ではありません。(極端な話、UTF-7 の可能性もあるわけで)

    よく知られる「ASCII」は、00〜7F までの 94 文字を定義したものですが、
    ASCII を国際化するために規定された ISO/IEC 646 においては、
    その中の 83 文字までが共通で(BCT)、残り 12 文字(IRV)は
    各国の記号に指し換わっています。

    ASCII で 5C は『\』ですが、日本語 JIS X 0201 では『¥』です。
    ASCII で 7E は『〜』ですが、日本語 JIS X 0201 では『 ̄』です。

    (掲示板の都合上、鍵括弧内の文字は
     似た形状の全角文字で代用表記しています)


    さらには、たとえば『大文字ウムラウトU』の文字のように、
    スウェーデンでは 5E (ASCII では『^』)にマッピングされていて、
    ドイツでは 5D (ASCII では『]』)にマッピングされるなどといった
    ケースもあります。

    http://ja.wikipedia.org/wiki/ISO/IEC_646
    http://www.asahi-net.or.jp/~ax2s-kmtn/ref/codes.html#ascii
    http://mikeneko.creator.club.ne.jp/~lab/kcode/encode.html


    とはいえ、ドイツ語などを扱う必要の無いアプリケーションなら、
    そのエンコードは最初から除外しておくことができるでしょう。
    そのためにも、「どんな文字コードが使われるのか」は、
    事前に絞り込んでおく事をお奨めします。


    > エンコードを自動判別して開く実装をしたいのですが、
    > どうすればいいでしょうか?

    ASCII の場合、80 以降のバイナリはありえませんし、
    Shift_JIS なら、2バイト文字の先導バイトに
    A0〜DF が来ることもありません。

    このようにして「存在してはならないバイナリ」が含まれていた場合に、
    その Encoding は使えないものとしてふるい落としていくことで、
    可能性のある Encoding を列挙するという手法を私は利用しています。

    ただし、先の例( E0 E8 →「琥」/「琲」)のように、複数の Encoding が
    取り出される可能性もあります。その場合は、ユーザーに選択して
    もらうとか、あるいはよく利用されているエンコードを優先するなどの
    処置が必要になってきますね。
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/

HOME HELP 新規作成 新着記事 トピック表示 発言ランク ファイル一覧 検索 過去ログ

- Child Tree -