Como ler um arquivo inteiro em uma string usando C #?

214

Qual é a maneira mais rápida de ler um arquivo de texto em uma variável de string?

Entendo que isso pode ser feito de várias maneiras, como ler bytes individuais e depois convertê-los em string. Eu estava procurando por um método com codificação mínima.

Shamim Hafiz
fonte
Verifique este stackoverflow.com/questions/2855335/…
Sandeep GB

Respostas:

373

Que tal File.ReadAllText:

string contents = File.ReadAllText(@"C:\temp\test.txt");
marc_s
fonte
3
Não é a melhor função para usar, no entanto. Como Devendra D. Chavan aponta em sua resposta, StreamReader.ReadToEndé mais eficiente.
precisa
40
@OwenBlacker Depende se "mais rápido" significa "menos tempo para executar" ou "menos tempo para entender".
bonh
2
O File.ReadAllText é definitivamente o mais fácil de usar, mas como "Devendra D. Chavan" ressalta, não é o mais rápido. Portanto, se você estiver lendo arquivos pequenos, seria uma opção melhor usar o File.ReadAllText.it realmente depende do tamanho dos arquivos de texto que você está lendo.
Mana
Para ler no servidor, verifique isso , a esperança ajuda alguém.
shaijut 07/07
1
@OwenBlacker - você tem certeza? O benchmark mostra que StreamReader.ReadToEndé mais eficiente que ReadAllLines. O que é de se esperar, pois o último também divide o texto em linhas. Mas estamos falando de um método diferente ReadAllText,. Na verdade, a resposta que você menciona mostra que ReadAllTextapenas liga StreamReader.ReadToEndinternamente.
Ed Avis
169

Uma comparação de referência de manipulação de arquivosFile.ReadAllLines vs a StreamReader ReadLinepartir de C #

Comparação de leitura de arquivo

Resultados. O StreamReader é muito mais rápido para arquivos grandes com mais de 10.000 linhas, mas a diferença para arquivos menores é insignificante. Como sempre, planeje tamanhos variados de arquivos e use File.ReadAllLines apenas quando o desempenho não for crítico.


Abordagem StreamReader

Como a File.ReadAllTextabordagem foi sugerida por outras pessoas, você também pode tentar mais rapidamente (não testei quantitativamente o impacto no desempenho, mas parece ser mais rápido do que File.ReadAllText(veja a comparação abaixo)). A diferença no desempenho será visível apenas no caso de arquivos maiores.

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


Comparação de File.Readxxx () vs StreamReader.Readxxx ()

Visualizando o código indicativo através ILSpy eu encontrei o seguinte sobre File.ReadAllLines, File.ReadAllText.

  • File.ReadAllText - Usa StreamReader.ReadToEndinternamente
  • File.ReadAllLines - Também usa StreamReader.ReadLineinternamente com a sobrecarga adicional de criar o List<string>retorno como linhas de leitura e loop até o final do arquivo.


Portanto, ambos os métodos são uma camada adicional de conveniência construída sobre ela StreamReader. Isso é evidente pelo corpo indicativo do método.

File.ReadAllText() implementação descompilada pelo 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;
}
Devendra D. Chavan
fonte
2
Você comparou contra File.ReadAllTexttambém?
marc_s 12/09
2
O ILSpy sugere que File.ReadAllText()é simplesmente um invólucro StreamReader.ReadToEnd(). Eu estou supondo que a camada adicional deve ter um desempenho um pouco mais lento que StreamReader.ReadToEnd().
Devendra D. Chavan
Ótima resposta. Talvez seja uma explicação um pouco demais para quem está procurando a solução, mas merece pelo menos tantos votos quanto a resposta escolhida.
Sandy Gifford
@Devendra D. Chavan: Offtopic, mas onde posso encontrar referência ou documentação para o ILSpy?
Viral Jain
1
Você também pode encontrar o código aqui: referencesource.microsoft.com/#mscorlib/system/io/… . O que eu não entendo é por que existe essa diferença significativa de velocidade se ReadAllTexté apenas um invólucro streamReader.ReadToEnd();?
Olivier Jacot-Descombes
6

Dê uma olhada no método File.ReadAllText ()

Algumas observações importantes:

Este método abre um arquivo, lê cada linha do arquivo e adiciona cada linha como um elemento de uma seqüência de caracteres. Em seguida, fecha o arquivo. Uma linha é definida como uma sequência de caracteres seguida por um retorno de carro ('\ r'), um avanço de linha ('\ n') ou um retorno de carro imediatamente seguido por um avanço de linha. A sequência resultante não contém o retorno de carro final e / ou avanço de linha.

Este método tenta detectar automaticamente a codificação de um arquivo com base na presença de marcas de ordem de bytes. Os formatos de codificação UTF-8 e UTF-32 (big endian e little-endian) podem ser detectados.

Use a sobrecarga do método ReadAllText (String, Encoding) ao ler arquivos que podem conter texto importado, porque caracteres não reconhecidos podem não ser lidos corretamente.

O identificador de arquivo é garantido para ser fechado por esse método, mesmo se houver exceções

sll
fonte
6

string text = File.ReadAllText("Path");você tem todo o texto em uma variável de sequência. Se você precisar de cada linha individualmente, poderá usar o seguinte:

string[] lines = File.ReadAllLines("Path");
Dilshod
fonte
4
System.IO.StreamReader myFile =
   new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();
Maxim V. Pavlov
fonte
4

@Cris sorry .This is quote MSDN Microsoft

Metodologia

Neste experimento, duas classes serão comparadas. A StreamReaderea FileStreamclasse será direcionado para ler dois arquivos de 10K e 200K em sua totalidade a partir do diretório do aplicativo.

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()

Resultado

insira a descrição da imagem aqui

FileStreamé obviamente mais rápido neste teste. Demora mais 50% a mais para StreamReaderler o arquivo pequeno. Para o arquivo grande, demorou mais 27% do tempo.

StreamReaderestá procurando especificamente quebras de linha, enquanto FileStreamisso não acontece. Isso será responsável por parte do tempo extra.

Recomendações

Dependendo do que o aplicativo precisa fazer com uma seção de dados, pode haver uma análise adicional que exigirá tempo de processamento adicional. Considere um cenário em que um arquivo tenha colunas de dados e as linhas sejam CR/LFdelimitadas. Ele StreamReaderfuncionaria na linha de texto procurando oe CR/LF, em seguida, o aplicativo faria uma análise adicional procurando um local específico de dados. (Você achou que String. SubString vem sem preço?)

Por outro lado, ele FileStreamlê os dados em partes e um desenvolvedor proativo pode escrever um pouco mais de lógica para usar o fluxo em seu benefício. Se os dados necessários estiverem em posições específicas no arquivo, esse certamente é o caminho a seguir, pois mantém o uso de memória baixo.

FileStream é o melhor mecanismo de velocidade, mas exigirá mais lógica.

MinhVuong
fonte
Mas que tal StreamReader.ReadToEnd?
Owen Blacker
3

bem, o significado da maneira mais rápida com o menor código C # possível é provavelmente este:

string readText = System.IO.File.ReadAllText(path);
Davide Piras
fonte
3

se você quiser escolher um arquivo da pasta Bin do aplicativo, tente seguir e não se esqueça de manipular exceções.

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

você pode usar :

 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);
    }
}
Erwin Draconis
fonte
2
string content = System.IO.File.ReadAllText( @"C:\file.txt" );
Paul Mitchell
fonte
2

Para os noobs por aí que acham essas coisas divertidas e interessantes, a maneira mais rápida de ler um arquivo inteiro em uma string na maioria dos casos (de acordo com esses benchmarks ) é o seguinte:

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

No entanto, o mais rápido absoluto para ler um arquivo de texto em geral parece ser o seguinte:

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

Contra várias outras técnicas , ganhou na maioria das vezes, inclusive contra o BufferedReader.


fonte
Os comentários estão atrasados, eu sei, mas um pouco confusos em seus benchmarks aqui e na página vinculada. Parece estar testando apenas as velocidades de leitura e não carregando em uma sequência inteira. O segundo trecho de código está lendo uma linha de cada vez e não faz nenhum acréscimo, portanto o "faça o que você precisa aqui" precisaria de um construtor de string ou string para armazenar os dados. Nesse ponto, a memória usada para adicionar mais dados alteraria os resultados do teste. Portanto, s normalmente terá o mesmo tamanho, assumindo um arquivo de largura fixa, para que a memória seja configurada para o tamanho de uma linha e os dados não precisem ser copiados para a nova memória.
Charles Byrne
2

Você pode usar assim

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 "";
        }
    }

Espero que isso ajude você.

Amit Kumawat
fonte
0

você pode ler um texto de um arquivo de texto para uma string da seguinte maneira:

string str = "";
StreamReader sr = new StreamReader(Application.StartupPath + "\\Sample.txt");
while(sr.Peek() != -1)
{
  str = str + sr.ReadLine();
}
Sai Kalyan Kumar Akshinthala
fonte
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);
                      }

                  }
              }
          }
      }
    }
JAY
fonte
0

Fiz uma comparação entre um ReadAllText e StreamBuffer para um csv de 2Mb e parecia que a diferença era bastante pequena, mas o ReadAllText parecia levar a vantagem dos tempos necessários para concluir as funções.

Hatitye Chindove
fonte