C#を使用してファイル全体を文字列に読み取る方法は?


214

テキストファイルを文字列変数に読み込む最も簡単な方法は何ですか。

個々のバイトを読み取り、それを文字列に変換するなど、いくつかの方法で実行できることを理解しています。最小限のコーディングでメソッドを探していました。


回答:


373

どのようにFile.ReadAllText

string contents = File.ReadAllText(@"C:\temp\test.txt");

3
ただし、使用するのに最適な関数ではありません。以下のようデヴェンドラD. Chavanが彼の答えで指摘し、StreamReader.ReadToEndより効率的です。
Owen Blacker 14年

40
@OwenBlackerそれは、「最も速い」が「実行する最小時間」を意味するか、「理解する最小時間」を意味するかによって異なります。
bon

2
File.ReadAllTextは間違いなく最も使いやすいものですが、「Devendra D. Chavan」が指摘するように、これは最速ではありません。したがって、小さなファイルを読み取る場合は、File.ReadAllText.itを使用する方が適切です。これは、読み取るテキストファイルの大きさによって異なります。
Mana

するには、サーバから読み込ん確認し、これを、希望は誰かに役立ちます。
shaijut 16

1
@OwenBlacker-よろしいですか?ベンチマークは、それStreamReader.ReadToEndがよりも効率的であることを示していますReadAllLines。後者もテキストを行に分割するため、これは予想されることです。しかし、ここでは別の方法について話しReadAllTextます。確かにあなたが言及した答えは、内部的にReadAllText呼び出すだけであることを示していますStreamReader.ReadToEnd
Ed Avis

169

ベンチマーク比較File.ReadAllLinesStreamReader ReadLineからC#のファイル処理

ファイル読み取り比較

結果。StreamReaderは、10,000行以上の大きなファイルの方がはるかに高速ですが、小さなファイルの違いは無視できます。いつものように、さまざまなサイズのファイルを計画し、パフォーマンスが重要でない場合にのみFile.ReadAllLinesを使用します。


StreamReaderアプローチ

他の人がこのFile.ReadAllTextアプローチを提案しているので、もっと早く試すこともできます(パフォーマンスへの影響を定量的にテストしていませんが、より速いようですFile.ReadAllText(以下の比較を参照))。 ただし、パフォーマンスの違いは、より大きなファイルの場合にのみ表示されます。

string readContents;
using (StreamReader streamReader = new StreamReader(path, Encoding.UTF8))
{
     readContents = streamReader.ReadToEnd();
}


File.Readxxx()とStreamReader.Readxxx()の比較

示すコードの表示ILSpy私が次を発見したがFile.ReadAllLinesFile.ReadAllText

  • File.ReadAllText - StreamReader.ReadToEnd内部で使用
  • File.ReadAllLines -また、StreamReader.ReadLine内部的に使用し、追加のオーバーヘッドを作成しList<string>て、読み取り行として返され、ファイルの終わりまでループします。


したがって、どちらの方法も、の上に構築された便利な追加レイヤーですStreamReader。これは、メソッドの指示本体によって明らかです。

File.ReadAllText() ILSpyによって逆コンパイルされた実装

public static string ReadAllText(string path)
{
    if (path == null)
    {
        throw new ArgumentNullException("path");
    }
    if (path.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
    }
    return File.InternalReadAllText(path, Encoding.UTF8);
}   

private static string InternalReadAllText(string path, Encoding encoding)
{
    string result;
    using (StreamReader streamReader = new StreamReader(path, encoding))
    {
        result = streamReader.ReadToEnd();
    }
    return result;
}

2
あなたも比較しましたFile.ReadAllTextか?
marc_s 2011

2
ILSpyは、これFile.ReadAllText()が単なるラッパーであることを示唆していますStreamReader.ReadToEnd()。追加のレイヤーのパフォーマンスは、のパフォーマンスよりもわずかに遅くなると思いますStreamReader.ReadToEnd()
Devendra D. Chavan

すばらしい答えです。おそらく、修正を探しているだけの人には少しだけ説明がありますが、少なくとも、選択した回答と同じ数の票を投じる価値があります。
サンディギフォード14

@Devendra D. Chavan:オフトピックですが、ILSpyのリファレンスやドキュメントはどこにありますか?
Viral Jain、

1
また、コードはreferencesource.microsoft.com/#mscorlib/system/io/…にもあります。私が得られないのは、ReadAllText単なるラッパーである場合、なぜ速度にこの大きな違いがあるのstreamReader.ReadToEnd();ですか?
Olivier Jacot-Descombes


6

File.ReadAllText()メソッドを見てください。

いくつかの重要な注意:

このメソッドは、ファイルを開き、ファイルの各行を読み取り、各行を文字列の要素として追加します。その後、ファイルを閉じます。行は、一連の文字の後にキャリッジリターン( '\ r')、ラインフィード( '\ n')、またはキャリッジリターンの直後にラインフィードが続くものとして定義されます。結果の文字列には、終了のキャリッジリターンやラインフィードは含まれません。

このメソッドは、バイトオーダーマークの存在に基づいて、ファイルのエンコーディングを自動的に検出しようとします。エンコーディング形式UTF-8およびUTF-32(ビッグエンディアンとリトルエンディアンの両方)を検出できます。

インポートされたテキストを含む可能性のあるファイルを読み取るときは、ReadAllText(String、Encoding)メソッドオーバーロードを使用してください。認識されない文字が正しく読み取られない可能性があるためです。

例外が発生した場合でも、ファイルハンドルはこのメソッドによって確実に閉じられます。


6

string text = File.ReadAllText("Path");1つの文字列変数にすべてのテキストがあります。各行が個別に必要な場合は、これを使用できます。

string[] lines = File.ReadAllLines("Path");


4

@クリス申し訳ありません。これは引用です MSDN Microsoft

方法論

この実験では、2つのクラスを比較します。StreamReaderおよびFileStreamアプリケーションディレクトリから、その全体が10Kと200Kの2つのファイルを読むためにクラス指示されます。

StreamReader (VB.NET)

sr = New StreamReader(strFileName)
Do
  line = sr.ReadLine()
Loop Until line Is Nothing
sr.Close()

FileStream (VB.NET)

Dim fs As FileStream
Dim temp As UTF8Encoding = New UTF8Encoding(True)
Dim b(1024) As Byte
fs = File.OpenRead(strFileName)
Do While fs.Read(b, 0, b.Length) > 0
    temp.GetString(b, 0, b.Length)
Loop
fs.Close()

結果

ここに画像の説明を入力してください

FileStreamこのテストでは明らかに高速です。StreamReader小さなファイルを読み取るには、さらに50%以上時間がかかります。大きなファイルの場合、さらに27%の時間がかかりました。

StreamReaderは特に改行を探しFileStreamていますが、そうではありません。これは、余分な時間の一部を占めます。

推奨事項

アプリケーションがデータのセクションをどのように処理する必要があるかに応じて、追加の処理時間を必要とする追加の解析が行われる場合があります。ファイルにデータの列があり、行がCR/LF区切られているシナリオを考えます。StreamReader探しているテキストの行を下に働くだろうCR/LFし、アプリケーションは、データの特定の場所を探して追加の解析を行うだろう。(あなたはStringだと思いましたか?SubStringは価格なしで来ますか?)

一方、FileStreamデータはチャンクで読み取られ、プロアクティブな開発者は、もう少しロジックを書き込んでストリームを使用することができます。必要なデータがファイル内の特定の位置にある場合は、メモリ使用量を抑えるため、これが確実な方法です。

FileStream 速度のための優れたメカニズムですが、より多くのロジックが必要になります。


しかし、どうStreamReader.ReadToEndですか?
オーウェンブラッカー2014年

3

可能な限り最小限のC#コードを使用した最も迅速な方法の意味は、おそらくこれです。

string readText = System.IO.File.ReadAllText(path);

3

アプリケーションのBinフォルダーからファイルを選択する場合は、以下を試して、例外処理を行うことを忘れないでください。

string content = File.ReadAllText(Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"FilesFolder\Sample.txt"));

3

あなたが使うことができます:

 public static void ReadFileToEnd()
{
    try
    {
    //provide to reader your complete text file
        using (StreamReader sr = new StreamReader("TestFile.txt"))
        {
            String line = sr.ReadToEnd();
            Console.WriteLine(line);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("The file could not be read:");
        Console.WriteLine(e.Message);
    }
}


2

これが楽しくて面白いと思う初心者にとって、ほとんどの場合(これらのベンチマークによると)、ファイル全体を文字列に読み取る最も速い方法は次のとおりです。

using (StreamReader sr = File.OpenText(fileName))
{
        string s = sr.ReadToEnd();
}
//you then have to process the string

ただし、テキストファイルを全体的に最も速く読み取るのは次のようです。

using (StreamReader sr = File.OpenText(fileName))
{
        string s = String.Empty;
        while ((s = sr.ReadLine()) != null)
        {
               //do what you have to here
        }
}

他のいくつかの手法に対抗すると、BufferedReaderを含め、ほとんどの場合勝ちました。


コメントは遅いですが、ベンチマークとリンク先のページで少し混乱しています。読み取り速度のみをテストしているようであり、文字列全体にロードされていないようです。2番目のコードスニペットは一度に1行ずつ読み取り、追加を行わないため、「ここまでの操作を行う」には、データを保持する文字列ビルダーまたは文字列が必要です。その時点で、さらにデータを追加するために使用されたメモリがテスト結果を変更します。したがって、sは通常、固定幅ファイルを想定して同じサイズになるため、メモリはラインのサイズに設定され、データを新しいメモリにコピーする必要はありません。
Charles Byrne

2

このように使えます

public static string ReadFileAndFetchStringInSingleLine(string file)
    {
        StringBuilder sb;
        try
        {
            sb = new StringBuilder();
            using (FileStream fs = File.Open(file, FileMode.Open))
            {
                using (BufferedStream bs = new BufferedStream(fs))
                {
                    using (StreamReader sr = new StreamReader(bs))
                    {
                        string str;
                        while ((str = sr.ReadLine()) != null)
                        {
                            sb.Append(str);
                        }
                    }
                }
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            return "";
        }
    }

これがお役に立てば幸いです。


0

次のように、テキストファイルから文字列にテキストを読み取ることもできます

string str = "";
StreamReader sr = new StreamReader(Application.StartupPath + "\\Sample.txt");
while(sr.Peek() != -1)
{
  str = str + sr.ReadLine();
}

0
public partial class Testfile : System.Web.UI.Page
{
    public delegate void DelegateWriteToDB(string Inputstring);
    protected void Page_Load(object sender, EventArgs e)
    {
        getcontent(@"C:\Working\Teradata\New folder");
    }

      private void SendDataToDB(string data)
    {
        //InsertIntoData
          //Provider=SQLNCLI10.1;Integrated Security=SSPI;Persist Security Info=False;User ID="";Initial Catalog=kannan;Data Source=jaya;
        SqlConnection Conn = new SqlConnection("Data Source=aras;Initial Catalog=kannan;Integrated Security=true;");
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = Conn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "insert into test_file values('"+data+"')";
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
        cmd.Connection.Close();
    }

      private void getcontent(string path)
      {
          string[] files;
          files = Directory.GetFiles(path, "*.txt");
          StringBuilder sbData = new StringBuilder();
          StringBuilder sbErrorData = new StringBuilder();
          Testfile df = new Testfile();
          DelegateWriteToDB objDelegate = new DelegateWriteToDB(df.SendDataToDB);
          //dt.Columns.Add("Data",Type.GetType("System.String"));


          foreach (string file in files)
          {
              using (StreamReader sr = new StreamReader(file))
              {
                  String line;
                  int linelength;
                  string space = string.Empty;

                  // Read and display lines from the file until the end of 
                  // the file is reached.
                  while ((line = sr.ReadLine()) != null)
                  {
                      linelength = line.Length;
                      switch (linelength)
                      {
                          case 5:
                              space = "     ";
                              break;

                      }
                      if (linelength == 5)
                      {
                          IAsyncResult ObjAsynch = objDelegate.BeginInvoke(line + space, null, null);
                      }
                      else if (linelength == 10)
                      {
                          IAsyncResult ObjAsynch = objDelegate.BeginInvoke(line , null, null);
                      }

                  }
              }
          }
      }
    }

0

2MbのcsvについてReadAllTextとStreamBufferを比較しましたが、差はかなり小さいように見えましたが、ReadAllTextは関数を完了するのにかかる時間よりも優位に立っているように見えました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.