Qual è il modo più veloce per leggere un file di testo in una variabile stringa?
Capisco che può essere fatto in diversi modi, come leggere singoli byte e poi convertirli in stringa. Stavo cercando un metodo con una codifica minima.
Qual è il modo più veloce per leggere un file di testo in una variabile stringa?
Capisco che può essere fatto in diversi modi, come leggere singoli byte e poi convertirli in stringa. Stavo cercando un metodo con una codifica minima.
Risposte:
Che ne dici di File.ReadAllText
:
string contents = File.ReadAllText(@"C:\temp\test.txt");
StreamReader.ReadToEnd
è più efficiente.
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 ReadAllText
chiama solo StreamReader.ReadToEnd
internamente.
Un confronto comparativo tra File.ReadAllLines
vs StreamReader ReadLine
dalla gestione dei file C #
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.
Poiché l' File.ReadAllText
approccio è 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();
}
Visualizzazione del codice di indicativa attraverso ILSpy ho trovato quanto segue riguardo File.ReadAllLines
, File.ReadAllText
.
File.ReadAllText
- Utilizza StreamReader.ReadToEnd
internamenteFile.ReadAllLines
- Utilizza anche StreamReader.ReadLine
internamente 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;
}
File.ReadAllText
??
File.ReadAllText()
è semplicemente un wrapper StreamReader.ReadToEnd()
. Immagino che il livello aggiuntivo dovrebbe funzionare leggermente più lentamente di StreamReader.ReadToEnd()
.
ReadAllText
è solo un involucro per streamReader.ReadToEnd();
?
string contents = System.IO.File.ReadAllText(path)
Ecco la documentazione MSDN
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
System.IO.StreamReader myFile =
new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();
@Cris scusa. Questa è la citazione MSDN Microsoft
Metodologia
In questo esperimento verranno confrontate due classi. La StreamReader
e la FileStream
classe 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
FileStream
è ovviamente più veloce in questo test. Ci vuole un ulteriore 50% di tempo in più per StreamReader
leggere 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 FileStream
non 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/LF
delimitate. L' StreamReader
avrebbe 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, FileStream
legge 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.
StreamReader.ReadToEnd
?
beh, il modo più rapido per indicare con il codice C # meno possibile è probabilmente questo:
string readText = System.IO.File.ReadAllText(path);
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);
}
}
string content = System.IO.File.ReadAllText( @"C:\file.txt" );
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.
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.
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();
}
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);
}
}
}
}
}
}
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.