Як прочитати весь файл до рядка за допомогою C #?


215

Який найшвидший спосіб прочитати текстовий файл у змінну рядка?

Я розумію, що це можна зробити кількома способами, наприклад, читати окремі байти, а потім перетворювати їх у рядок. Я шукав метод з мінімальним кодуванням.


Відповіді:


373

Як щодо File.ReadAllText:

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

3
Хоча не найкраща функція для використання. Як вказує у своїй відповіді Девендра Д. Шаван , StreamReader.ReadToEndце більш ефективно.
Оуен Блекер

40
@OwenBlacker Це залежить від того, "швидкий" означає "найменший час для виконання" або "найменший час для розуміння".
бон

2
File.ReadAllText, безумовно, найпростіший у використанні, але, як вказує "Девендра Д. Шаван", він не найшвидший. Отже, якщо ви читаєте невеликі файли, тоді буде кращим вибором використовувати File.ReadAllText.it насправді залежить від того, наскільки великі текстові файли ви читаєте.
Мана

Щоб прочитати з сервера перевірити це , сподіваюся, що хтось допоможе.
shaijut

1
@OwenBlacker - ви впевнені? Тест показує, що StreamReader.ReadToEndце більш ефективно, ніж ReadAllLines. Що варто очікувати, оскільки останній також розбиває текст на рядки. Але ми говоримо про інше методі ReadAllText. Дійсно, відповідь, яку ви згадуєте, показує, що ReadAllTextпросто дзвонить StreamReader.ReadToEndвнутрішньо.
Ed Avis

170

Порівняльне порівняння File.ReadAllLinesпорівняно StreamReader 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.ReadAllLines, File.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

2
ILSpy припускає, що File.ReadAllText()це просто обгортка StreamReader.ReadToEnd(). Я здогадуюсь, що додатковий шар повинен виконуватись трохи повільніше, ніж StreamReader.ReadToEnd().
Девендра Д. Шаван

Чудова відповідь. Можливо, трохи пояснення для тих, хто просто шукає виправлення, але воно заслуговує принаймні стільки ж голосів, скільки обрана відповідь.
Сенді Гіффорд

@Devendra D. Chavan: Offtopic, але де я можу знайти посилання або документацію для ILSpy?
Вірусна Джайн

1
Ви також можете знайти код тут: referenceource.microsoft.com/#mscorlib/system/io/… . Що я не розумію, чому є така значна різниця у швидкості, якщо ReadAllTextце лише обгортка streamReader.ReadToEnd();?
Олів'є Якот-Дескомб


6

Погляньте на метод File.ReadAllText ()

Деякі важливі зауваження:

Цей метод відкриває файл, читає кожен рядок файлу, а потім додає кожен рядок як елемент рядка. Потім він закриває файл. Рядок визначається як послідовність символів з подальшим поверненням каретки ('\ r'), стрічкою рядка ('\ n') або поверненням каретки, одразу після якого подається лінія. Отриманий рядок не містить завершального повернення каретки та / або каналу рядка.

Цей метод намагається автоматично виявити кодування файлу на основі наявності знаків порядку байтів. Формати кодування UTF-8 та UTF-32 (як big-endian, так і little-endian) можуть бути виявлені.

Використовуйте перевантажений метод ReadAllText (String, Encoding) при читанні файлів, які можуть містити імпортований текст, оскільки нерозпізнані символи можуть бути прочитані неправильно.

Гарантія файлу гарантовано закриється цим методом, навіть якщо винятки становлять


6

string text = File.ReadAllText("Path");у вас є весь текст в одній змінній рядку. Якщо вам потрібен кожен рядок окремо, ви можете скористатися цим:

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


4

@Cris вибачте. Це цитата MSDN Microsoft

Методика

У цьому експерименті буде порівняно два класи. Клас StreamReaderі FileStreamбуде спрямовано на зчитування двох файлів розміром 10 К і 200 К у повному обсязі з каталогу додатків.

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?
Оуен Блекер

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.


Я зауважую, що коментар запізнився, але трохи замішаний у ваших орієнтирах тут і на пов'язаній сторінці. Схоже, тестується лише швидкість читання, а не завантажується в цілий рядок. Другий фрагмент коду - це читати рядок за один раз і не робити додавання, тому "робити те, що вам тут доведеться", повинен мати конструктор рядків або рядок для зберігання даних. У цей момент пам'ять, яка використовується для додавання більше даних, змінила б результати тестів. Таким чином, s зазвичай буде однакового розміру, припускаючи файл фіксованої ширини, тому пам'ять буде встановлена ​​для розміру рядка, і дані не потрібно буде копіювати в нову пам'ять.
Чарльз Берн

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

Я зробив порівняння між ReadAllText та StreamBuffer для 2 Мб csv, і здавалося, що різниця була досить невеликою, але ReadAllText, здавалося, взяв верх за час, який потрібно виконати для виконання функцій.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.