0

私が行っているプロジェクトのリストの一部は、小さなテキスト エディターです。

ある時点で、特定のディレクトリ内のすべてのサブディレクトリとファイルをロードできます。プログラムはそれぞれを TreeView のノードとして追加します。

この機能を実現したいのは、通常のテキスト リーダーで読み取り可能なファイルのみを追加することです。

このコードは現在、それをツリーに追加します:

TreeNode navNode = new TreeNode();
navNode.Text = file.Name;
navNode.Tag = file.FullName;

 directoryNode.Nodes.Add(navNode);

次のような if ステートメントを簡単に作成できることはわかっています。

if(file.extension.equals(".txt"))

しかし、可能性のあるすべての拡張子を含めるには、そのステートメントを拡張する必要があります。

これを行う簡単な方法はありますか?MIME タイプまたはファイル エンコーディングと関係があるのではないかと考えています。

4

4 に答える 4

4

ファイルに保存されている情報の種類を把握する一般的な方法はありません。

ある種のテキストであることを事前に知っていても、ファイルの作成に使用されたエンコーディングがわからない場合は、正しくロードできない可能性があります。

HTTPは、content-typeヘッダーごとにファイルのタイプに関するヒントを提供しますが、ファイルシステムにはそのような情報がないことに注意してください。

于 2013-01-22T01:10:18.730 に答える
1

@Rubenismeのコメントと@Erikの回答に基づく私のアプローチ。

    public static bool IsValidTextFile(string path)
    {
        using (var stream = System.IO.File.Open(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read))
        using (var reader = new System.IO.StreamReader(stream, System.Text.Encoding.UTF8)) 
        {
            var bytesRead = reader.ReadToEnd();
            reader.Close();
            return bytesRead.All(c => // Are all the characters either a:
                c == (char)10  // New line
                || c == (char)13 // Carriage Return
                || c == (char)11 // Tab
                || !char.IsControl(c) // Non-control (regular) character
                );
        }
    }
于 2016-11-04T19:40:12.967 に答える
1

ファイルがテキスト ファイルであるかどうかを "最もよく推測する" ために使用できる方法がいくつかあります。もちろん、サポートするエンコーディングが多ければ多いほど、特に CJK (中国語日本語韓国語) スクリプトのサポートを計画している場合は、これが難しくなります。Encoding.Ascii今のところ、そしてから始めましょうEncoding.UTF-8

幸いなことに、ほとんどの非テキスト ファイル (実行可能ファイル画像など)は、最初の数キロバイトに多くの解析不能文字が含まれています。

あなたができることは、ファイルを取得して最初の 1 ~ 4 KB (任意) をスキャンし、「印刷できない」文字が出てくるかどうかを確認することです。この操作にはそれほど時間はかからず、少なくともファイルの内容についてある程度の確実性が得られます。

public static async Task<bool> IsValidTextFileAsync(string path,
                                                    int scanLength = 4096)
{
  using(var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read))
  using(var reader = new StreamReader(stream, Encoding.UTF8))
  {
    var bufferLength = (int)Math.Min(scanLength, stream.Length);
    var buffer = new char[bufferLength];

    var bytesRead = await reader.ReadBlockAsync(buffer, 0, bufferLength);
    reader.Close();

    if(bytesRead != bufferLength)
      throw new IOException("There was an error reading from the file.");

    for(int i = 0; i < bytesRead; i++)
    {
      var c = buffer[i];

      if(char.IsControl(c))
        return false;
    }

    return true;
  }
}
于 2013-01-22T01:27:11.700 に答える
0

これを行うハックな方法は、空白の形式ではない下位制御文字 (0-31) がファイルに含まれているかどうかを確認することです (キャリッジ リターン、タブ、垂直タブ、ライン フィード、および安全のためにnull およびテキストの終わり)。もしそうなら、それはおそらくバイナリです。そうでない場合は、おそらくそうではありません。このルールを非ASCIIエンコーディングに適用するとどうなるかを確認するためのテストや何かを行っていないため、自分でさらに調査する必要があります:)

于 2013-01-22T01:15:00.887 に答える