Как прочитать весь файл в строку с помощью C #?


215

Какой самый быстрый способ прочитать текстовый файл в строковую переменную?

Я понимаю, что это можно сделать несколькими способами, например, прочитать отдельные байты, а затем преобразовать их в строку. Я искал метод с минимальным кодированием.


Ответы:


374

Как насчет File.ReadAllText:

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

3
Не самая лучшая функция для использования. Как указывает Девендра Д. Чаван в своем ответе, StreamReader.ReadToEndон более эффективен.
Оуэн Блэкер

40
@OwenBlacker Это зависит от того, означает ли «самый быстрый» «наименьшее время для выполнения» или «наименьшее время для понимания».
Бон

2
File.ReadAllText, безусловно, самый простой в использовании, но, как указывает «Devendra D. Chavan», он не самый быстрый. Поэтому, если вы читаете небольшие файлы, то лучше использовать File.ReadAllText.it, в действительности это зависит от размера текстовых файлов, которые вы читаете.
Мана

Для чтения с сервера проверить это , надеюсь , поможет кому - то.
Шайют

1
@OwenBlacker - ты уверен? Тест показывает, что StreamReader.ReadToEndэто более эффективно, чем ReadAllLines. Что и следовало ожидать, так как последний также разбивает текст на строки. Но мы говорим о другом методе ReadAllText. Действительно, ответ, который вы упомянули, показывает, ReadAllTextчто звонит только StreamReader.ReadToEndвнутри.
Эд Авис

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: Оффтоп, но где я могу найти справку или документацию по ILSpy?
Вирусный Джайн

1
Вы также можете найти код здесь: referenceource.microsoft.com/#mscorlib/system/io/… . Чего я не понимаю, ReadAllTextтак это большой разницы в скорости, если это просто оболочка streamReader.ReadToEnd();?
Оливье Жако-Дескомб


7

Посмотрите на File.ReadAllText () метод

Некоторые важные замечания:

Этот метод открывает файл, читает каждую строку файла, а затем добавляет каждую строку как элемент строки. Затем он закрывает файл. Строка определяется как последовательность символов, за которой следует возврат каретки ('\ r'), перевод строки ('\ n') или возврат каретки, за которым сразу следует перевод строки. Результирующая строка не содержит завершающего возврата каретки и / или перевода строки.

Этот метод пытается автоматически определить кодировку файла на основе наличия меток порядка байтов. Форматы кодирования UTF-8 и UTF-32 (как с прямым порядком байтов, так и с прямым порядком байтов) могут быть обнаружены.

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

Этот метод гарантированно закрывает дескриптор файла, даже если возникают исключения


6

string text = File.ReadAllText("Path");у вас есть весь текст в одной строковой переменной. Если вам нужна каждая строка отдельно, вы можете использовать это:

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


4

@ Крис извините. Это цитата MSDN Microsoft

методология

В этом эксперименте будут сравниваться два класса. Класс StreamReaderand FileStreamбудет направлен на чтение двух файлов по 10K и 200K полностью из каталога приложения.

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 для CSV 2 МБ, и казалось, что разница была довольно небольшой, но ReadAllText, казалось, взял верх над временем, затраченным на выполнение функций.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.