Come leggere un intero file in una stringa usando C #?


Risposte:


374

Che ne dici di File.ReadAllText:

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

3
Tuttavia, non è la funzione migliore da utilizzare. Come sottolinea Devendra D. Chavan nella sua risposta, StreamReader.ReadToEndè più efficiente.
Owen Blacker,

40
@OwenBlacker Dipende dal fatto che "più veloce" significhi "minor tempo di esecuzione" o "minor tempo di comprensione".
bonh,

2
File.ReadAllText è sicuramente il più semplice da usare, ma come sottolinea "Devendra D. Chavan", non è il più veloce. Quindi se stai leggendo piccoli file, sarebbe una scelta migliore usare File.ReadAllText.it dipende davvero da quanto sono grandi i file di testo che stai leggendo.
Mana,

Per leggere dal server controlla questo , spero che aiuti qualcuno.
Shaijut,

1
@OwenBlacker - sei sicuro? Il benchmark mostra che StreamReader.ReadToEndè più efficiente di ReadAllLines. Il che è prevedibile, poiché quest'ultimo divide anche il testo in righe. Ma stiamo parlando di un metodo diverso, ReadAllText. In effetti la risposta che menzioni mostra che ReadAllTextchiama solo StreamReader.ReadToEndinternamente.
Ed Avis,

170

Un confronto comparativo tra File.ReadAllLinesvs StreamReader ReadLinedalla gestione dei file C #

Confronto lettura file

Risultati. StreamReader è molto più veloce per file di grandi dimensioni con oltre 10.000 righe, ma la differenza per file più piccoli è trascurabile. Come sempre, pianificare per file di dimensioni variabili e utilizzare File.ReadAllLines solo quando le prestazioni non sono critiche.


Approccio StreamReader

Poiché l' File.ReadAllTextapproccio è stato suggerito da altri, puoi anche provare più velocemente (non ho testato quantitativamente l'impatto sulle prestazioni, ma sembra essere più veloce di File.ReadAllText(vedi confronto sotto)). La differenza nelle prestazioni sarà visibile solo in caso di file più grandi.

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


Confronto di File.Readxxx () vs StreamReader.Readxxx ()

Visualizzazione del codice di indicativa attraverso ILSpy ho trovato quanto segue riguardo File.ReadAllLines, File.ReadAllText.

  • File.ReadAllText - Utilizza StreamReader.ReadToEndinternamente
  • File.ReadAllLines - Utilizza anche StreamReader.ReadLineinternamente con l'overhead aggiuntivo di creare il List<string>da restituire come linee di lettura e loop fino alla fine del file.


Quindi entrambi i metodi sono un ulteriore livello di praticità costruito sopra StreamReader. Ciò è evidente dal corpo indicativo del metodo.

File.ReadAllText() implementazione decompilata da 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
Hai confrontato anche tu File.ReadAllText??
marc_s,

2
ILSpy suggerisce che File.ReadAllText()è semplicemente un wrapper StreamReader.ReadToEnd(). Immagino che il livello aggiuntivo dovrebbe funzionare leggermente più lentamente di StreamReader.ReadToEnd().
Devendra D. Chavan,

Bella risposta. Forse un po 'più di spiegazione per coloro che cercano solo la soluzione, ma merita almeno tanti voti quanto la risposta scelta.
Sandy Gifford,

@Devendra D. Chavan: Offtopic, ma dove posso trovare riferimenti o documentazione per ILSpy?
Viral Jain,

1
È inoltre possibile trovare il codice qui: riferimentiource.microsoft.com/#mscorlib/system/io/… . Quello che non capisco, è perché c'è questa differenza significativa nella velocità se ReadAllTextè solo un involucro per streamReader.ReadToEnd();?
Olivier Jacot-Descombes,


7

Dai un'occhiata al metodo File.ReadAllText ()

Alcune osservazioni importanti:

Questo metodo apre un file, legge ogni riga del file e quindi aggiunge ogni riga come elemento di una stringa. Quindi chiude il file. Una riga è definita come una sequenza di caratteri seguita da un ritorno a capo ('\ r'), un avanzamento riga ('\ n') o un ritorno a capo immediatamente seguito da un avanzamento riga. La stringa risultante non contiene il ritorno a capo terminante e / o l'alimentazione di riga.

Questo metodo tenta di rilevare automaticamente la codifica di un file in base alla presenza di segni di ordine byte. È possibile rilevare i formati di codifica UTF-8 e UTF-32 (sia big-endian che little-endian).

Utilizzare l'overload del metodo ReadAllText (String, Encoding) durante la lettura di file che potrebbero contenere testo importato, poiché i caratteri non riconosciuti potrebbero non essere letti correttamente.

L'handle di file è garantito per essere chiuso con questo metodo, anche se vengono sollevate eccezioni


6

string text = File.ReadAllText("Path");hai tutto il testo in una variabile stringa. Se hai bisogno di ogni riga singolarmente puoi usare questo:

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

4
System.IO.StreamReader myFile =
   new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();

4

@Cris scusa. Questa è la citazione MSDN Microsoft

Metodologia

In questo esperimento verranno confrontate due classi. La StreamReadere la FileStreamclasse sarà diretto per leggere due file di 10K e 200K nella loro interezza dalla directory dell'applicazione.

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

Risultato

inserisci qui la descrizione dell'immagine

FileStreamè ovviamente più veloce in questo test. Ci vuole un ulteriore 50% di tempo in più per StreamReaderleggere il piccolo file. Per i file di grandi dimensioni, ci è voluto un ulteriore 27% delle volte.

StreamReaderè specificamente alla ricerca di interruzioni di riga mentre FileStreamnon lo fa. Questo spiegherà alcuni dei tempi supplementari.

raccomandazioni

A seconda di ciò che l'applicazione deve fare con una sezione di dati, potrebbe essere necessario un ulteriore analisi che richiederà tempi di elaborazione aggiuntivi. Si consideri uno scenario in cui un file ha colonne di dati e le righe sono CR/LFdelimitate. L' StreamReaderavrebbe funzionato lungo la riga di testo alla ricerca del CR/LF, e quindi l'applicazione farebbe parsing ulteriore ricerca di una posizione specifica dei dati. (Hai pensato String. SubString arriva senza un prezzo?)

D'altra parte, FileStreamlegge i dati in blocchi e uno sviluppatore proattivo potrebbe scrivere un po 'più di logica per utilizzare il flusso a suo vantaggio. Se i dati necessari si trovano in posizioni specifiche nel file, questa è sicuramente la strada da percorrere poiché mantiene basso l'utilizzo della memoria.

FileStream è il meccanismo migliore per la velocità ma richiederà più logica.


Ma che dire StreamReader.ReadToEnd?
Owen Blacker,

3

beh, il modo più rapido per indicare con il codice C # meno possibile è probabilmente questo:

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

3

se vuoi selezionare il file dalla cartella Bin dell'applicazione, puoi provare a seguire e non dimenticare di fare la gestione delle eccezioni.

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

3

Puoi usare :

 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

Per i rumori là fuori che trovano questa roba divertente e interessante, il modo più veloce per leggere un intero file in una stringa nella maggior parte dei casi ( secondo questi benchmark ) è il seguente:

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

Tuttavia, il più veloce in assoluto per leggere un file di testo in generale sembra essere il seguente:

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

Messo a confronto con molte altre tecniche , ha vinto la maggior parte del tempo, anche contro il BufferedReader.


Il commento è in ritardo, lo so, ma un po 'confuso sui tuoi benchmark qui e sulla pagina collegata. Sembra testare solo le velocità di lettura e non caricare in un'intera stringa. Il secondo frammento di codice sta leggendo una riga alla volta e non sta facendo alcun accodamento, quindi il "fai quello che devi fare qui" dovrebbe avere un generatore di stringhe o una stringa per contenere i dati. A quel punto la memoria utilizzata per aggiungere più dati cambierebbe i risultati del test. Quindi, s avrà normalmente le stesse dimensioni assumendo un file a larghezza fissa, quindi la memoria verrà impostata per le dimensioni di una linea e i dati non dovranno essere copiati in una nuova memoria.
Charles Byrne,

2

Puoi usare così

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

Spero che questo ti possa aiutare.


0

puoi leggere un testo da un file di testo in stringa come segue anche

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

Ho fatto un confronto tra un ReadAllText e StreamBuffer per un csv da 2 Mb e mi è sembrato che la differenza fosse piuttosto piccola, ma ReadAllText sembrava prendere il sopravvento dai tempi impiegati per completare le funzioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.