mikan's technical note

仕事&趣味で実験した小技の備忘録です(Linux,windows,DOS等)

MENU

【C#】ファイルの文字エンコード判定

テキストファイルを読んでとある処理をさせていたところ、
UTF-8は問題ないが、Shift-JISで文字化けが発生。

ファイルのエンコードを判断できないか調べてみたが
完璧な判断ロジックは存在しないらしく、
基本的な判断でさえそれなりのロジックが必要なことがわかった。

hnx8氏が公開している「ReadJEnc」という便利なDLLを発見したので
試してみました。※C#で書かれていてソースも公開されています
d.hatena.ne.jp


【実行結果】※ReanEncの結果で、StreamReader()に文字エンコードを指定する
f:id:myerss555:20170205154905p:plain

//
// 【ファイルの文字エンコード判定】※Windows7で動作確認済み
// (c) 2017 mikan
// ※使用にあたっては利用者の自己責任でお願いします。
// ※このサンプルは、UTF-8とShift-JISのみ対応
//
using System;
using System.IO;

namespace EncodeCheck
{
    class Program
    {
        static void Main(string[] args)
        {
            string str;

            // エンコード取得
            foreach (string s in args)
            {
                Console.WriteLine("--------------------------------------------------");
                Console.WriteLine("ファイル名:{0}", s);
                str = CodeCheck(s);
                Console.WriteLine("エンコード:{0}", str);
                Console.WriteLine("--------------------------------------------------");
                fileread(s, str);
                Console.WriteLine("\n");
            }
        }

        // ファイル表示
        static int fileread(string fname, string encoding)
        {
            string ENCODE_STR;

            if (encoding == "ShiftJIS")
            {
                ENCODE_STR = "shift_jis";
            }
            else
            {
                ENCODE_STR = "utf-8";
            }

            // ファイルオープン
            System.IO.StreamReader sr = new
                System.IO.StreamReader(
                    fname, System.Text.Encoding.GetEncoding(ENCODE_STR));

            // 一行ずつ読み込み
            while (sr.Peek() > -1)
            {
        // 上のStreamReader()で文字エンコードを指定していないと
                // コンソール出力でShift-JISが文字化けする
                Console.WriteLine(sr.ReadLine());
            }
            sr.Close();

            return 0;
        }

        // 文字エンコード取得
        static string CodeCheck(string fname)
        {
            string str = null;

            // ファイルをbyte形で全て読み込み
            FileStream fs = new FileStream(fname, FileMode.Open);
            byte[] data = new byte[fs.Length];
            fs.Read(data, 0, data.Length);
            fs.Close();

            // 文字エンコード推定(hnx8氏公開のDLL)
            var charCode =
                Hnx8.ReadJEnc.ReadJEnc.JP.GetEncoding(data, data.Length, out str);

            return charCode.ToString();
        }
    }
}

【C#】改行コードCRLF(0x0d0a)形式ファイルを、改行コードLF(0x0a)形式ファイルに変換

//
// 【改行コード CRLF(0x0d0a) -> LF(0x0a)】※Windows7で動作確認済
// (c) 2017 mikan
// ※使用にあたっては利用者の自己責任でお願いします。
//
using System;
using System.IO;

namespace CRLFtoLF
{
    class Program
    {
        static void Main(string[] args)
        {
            string str;

            // ※既存ファイルへの上書きチェック等は別途行ってください
            if (args.Length != 2) {
                Console.WriteLine("パラメータエラー");
                return;
            }

            // 入力ファイルを全て読み込み(byte型)
            FileStream fs1 = new FileStream(args[0], FileMode.Open);
            byte[] data = new byte[fs1.Length];
            fs1.Read(data, 0, data.Length);
            fs1.Close();

            // 出力ファイルオープン(バイナリ形式)
            FileStream fs2 = new FileStream(args[1], FileMode.Create);
            BinaryWriter bw = new BinaryWriter(fs2);

            // 1byteずつ書き込み(0x0dを削除)
            for(int i = 0; i < data.Length; i ++) {
                if(data[i] == 0x0d)
                {
                    continue;
                }
                bw.Write(data[i]);
            }

            // 出力ファイルクローズ
            bw.Close();
            fs2.Close();
        }
    }
}