10

FileStream を使用してファイルを変更しています (非常に大きなファイルであり、全体を書き換えずにヘッダーを変更するだけです。

ファイルには Unix と Windows のいずれかの改行を含めることができます。ファイルを更新するときに正しい改行文字をファイルに書き戻せるように、どちらを知っているかが重要です。

FileStream を使用してファイルをブロック単位で読み取り、改行文字をチェックする単純な関数を作成できます。

しかし、この問題は以前に解決されているに違いありません。C# ではなく、Win32 API で解決されているのでしょうか?

ファイルの改行スタイルを検出する最も効率的な方法は何ですか?

4

3 に答える 3

4

ご提案いただきありがとうございます。簡単に再利用できるものが見つからないことに驚いたので、ここに含める簡単な関数を作成しました。最初の改行文字 (\n または \r\n) を検索し、それを一致として返すことに注意してください。私のニーズには十分ですが、おそらく堅牢ではありません。

    public bool TryDetectNewLine(string path, out string newLine)
    {
        using (var fileStream = File.OpenRead(path))
        {
            char prevChar = '\0';

            // Read the first 4000 characters to try and find a newline
            for (int i = 0; i < 4000; i++)
            {
                int b;
                if ((b = fileStream.ReadByte()) == -1) break;

                char curChar = (char)b;

                if (curChar == '\n')
                {
                    newLine = prevChar == '\r' ? "\r\n" : "\n";
                    return true;
                }

                prevChar = curChar;
            }

            // Returning false means could not determine linefeed convention
            newLine = Environment.NewLine;
            return false;
        }
    }
于 2012-08-06T16:46:28.970 に答える
3

Perが述べたように、テキストファイルを開いてバイトをストリーミングせずに、テキストファイルの内容を決定する方法は実際にはありません。http を使用してファイルをダウンロードすると、ファイルのタイプを示す MIME タイプを取得できる場合がありますが、ほとんどの場合、それは単なる「オクテット ストリーム」です。

ブルート フォースで改行 ("\n") が見つかるまで読んでから、1 文字戻ってキャリッジ リターン ("\r") があるかどうかを確認できますが、任意の方法でデータを読み取ります。

1) ファイルから少なくとも 2 つまたは 3 つのレコードを取得するサンプル サイズのバイトを選択して読み込みます。

2) 遭遇した各バイト (i'massumign single byte char set here) をヒストグラムとして保存します。これを行うには、バイト値でインデックス付けされた配列にカウントを格納するか、辞書を使用できます。

3) キャリッジ リターンとライン フィードの値のカウントを確認します。改行があり、キャリッジ リターンがない場合は、UNIX ファイルです。キャリッジ リターンとライン フィードがカウントされる場合、それは Windows ファイルです。

このアプローチでできることは、受信ファイルの品質チェックです。ヒストグラムにアルファ数値ではない文字がありますか? 次に、誰かがあなたにバイナリ ファイルを渡しました。すべて大文字が必要ですか? 次に、大文字以外のカウントを探します。テキスト以外のファイルを処理しないようにするために実行できるチェックがいくつかあります。

于 2012-08-06T14:41:40.640 に答える
2

残念ながら、Unix ファイルか DOS ファイルかを 100% 確実にする方法はないと思います。ほとんどのエディターは、開いたり保存したときに「間違った」末尾のファイルを修正しないからです。

ファイルをストリームとして読み取り、「\r\n」と「\n」のみを検索します

検索結果に対して単純な統計分析 (つまり、どれが最もヒット数が多いか) を使用すると、正しい答えが得られる可能性があります。ファイルが巨大な場合は、ファイルの最初の X% を読み取るだけで十分です。

もちろん、より簡単な解決策は、「\r\n」のみを検索し、見つかった場合はそれが DOS ファイルであると想定することです。ファイルがマシン生成されている場合、これは 100% まで機能するはずです。

.NET Framework/WinAPI の既存のコードに関しては、この操作を実行するコードはまだ見たことがありません。

于 2012-08-06T14:17:13.273 に答える