¿Cómo leer un archivo completo en una cadena usando C #?
214
¿Cuál es la forma más rápida de leer un archivo de texto en una variable de cadena?
Entiendo que se puede hacer de varias maneras, como leer bytes individuales y luego convertirlos en cadenas. Estaba buscando un método con una codificación mínima.
Sin embargo, no es la mejor función para usar. Como Devendra D. Chavan señala en su respuesta, StreamReader.ReadToEndes más eficiente.
Owen Blacker
40
@OwenBlacker Depende de si "más rápido" significa "menos tiempo para ejecutar" o "menos tiempo para comprender".
bonh
2
File.ReadAllText es definitivamente el más fácil de usar, pero como señala "Devendra D. Chavan", no es el más rápido. Entonces, si está leyendo archivos pequeños, entonces sería una mejor opción usar File.ReadAllText.Depende realmente de qué tan grandes sean los archivos de texto que esté leyendo.
Mana
Para leer desde el servidor, verifique esto , la esperanza ayuda a alguien.
shaijut
1
@OwenBlacker: ¿estás seguro? El punto de referencia muestra que StreamReader.ReadToEndes más eficiente que ReadAllLines. Lo cual es de esperar, ya que este último también divide el texto en líneas. Pero estamos hablando de un método diferente, ReadAllText. De hecho, la respuesta que menciona muestra que ReadAllTextsolo llama StreamReader.ReadToEndinternamente.
Ed Avis
169
Una comparación de referencia del manejo de archivos CFile.ReadAllLines vs StreamReader ReadLinede
Resultados StreamReader es mucho más rápido para archivos grandes con más de 10,000 líneas, pero la diferencia para archivos más pequeños es insignificante. Como siempre, planifique diferentes tamaños de archivos y use File.ReadAllLines solo cuando el rendimiento no sea crítico.
Enfoque StreamReader
Como el File.ReadAllTextenfoque ha sido sugerido por otros, también puede intentarlo más rápido (no he probado cuantitativamente el impacto en el rendimiento, pero parece ser más rápido que File.ReadAllText(ver la comparación a continuación)). Sin embargo, la diferencia en el rendimiento será visible solo en el caso de archivos más grandes.
string readContents;
using (StreamReader streamReader =newStreamReader(path,Encoding.UTF8)){
readContents = streamReader.ReadToEnd();}
Comparación de File.Readxxx () vs StreamReader.Readxxx ()
Visualización del código indicativo través ILSpy he encontrado lo siguiente acerca de File.ReadAllLines, File.ReadAllText.
File.ReadAllLines - También se usa StreamReader.ReadLineinternamente con la sobrecarga adicional de crear el List<string>retorno como líneas de lectura y bucles hasta el final del archivo.
Por lo tanto, ambos métodos son una capa adicional de conveniencia construida además StreamReader. Esto es evidente por el cuerpo indicativo del método.
File.ReadAllText() implementación como descompilada por ILSpy
publicstaticstringReadAllText(string path){if(path ==null){thrownewArgumentNullException("path");}if(path.Length==0){thrownewArgumentException(Environment.GetResourceString("Argument_EmptyPath"));}returnFile.InternalReadAllText(path,Encoding.UTF8);}privatestaticstringInternalReadAllText(string path,Encoding encoding){string result;
using (StreamReader streamReader =newStreamReader(path, encoding)){
result = streamReader.ReadToEnd();}return result;}
ILSpy sugiere que File.ReadAllText()es simplemente una envoltura StreamReader.ReadToEnd(). Supongo que la capa adicional debería funcionar un poco más lento que StreamReader.ReadToEnd().
Devendra D. Chavan
Gran respuesta. Quizás una pequeña explicación para aquellos que solo buscan la solución, pero merece al menos tantos votos como la respuesta elegida.
Sandy Gifford
@Devendra D. Chavan: Offtopic, pero ¿dónde puedo encontrar referencias o documentación para ILSpy?
Viral Jain
1
También puede encontrar el código aquí: referencesource.microsoft.com/#mscorlib/system/io/… . Lo que no entiendo, es ¿por qué existe esta diferencia significativa en la velocidad si ReadAllTextsolo es una envoltura streamReader.ReadToEnd();?
Este método abre un archivo, lee cada línea del archivo y luego agrega cada línea como un elemento de una cadena. Luego cierra el archivo. Una línea se define como una secuencia de caracteres seguida de un retorno de carro ('\ r'), un avance de línea ('\ n') o un retorno de carro seguido inmediatamente por un avance de línea. La cadena resultante no contiene el retorno de carro final y / o el avance de línea.
Este método intenta detectar automáticamente la codificación de un archivo en función de la presencia de marcas de orden de bytes. Se pueden detectar los formatos de codificación UTF-8 y UTF-32 (tanto big-endian como little-endian).
Utilice la sobrecarga del método ReadAllText (String, Encoding) al leer archivos que pueden contener texto importado, porque los caracteres no reconocidos pueden no leerse correctamente.
Se garantiza que el identificador de archivo se cierre con este método, incluso si se generan excepciones
En este experimento, se compararán dos clases. El StreamReadery la FileStreamclase serán dirigidos a leer dos archivos de 10K y 200K en su totalidad desde el directorio de la aplicación.
StreamReader(VB.NET)
sr =NewStreamReader(strFileName)Do
line = sr.ReadLine()LoopUntil line IsNothing
sr.Close()FileStream(VB.NET)Dim fs AsFileStreamDim temp As UTF8Encoding =New UTF8Encoding(True)Dim b(1024)AsByte
fs =File.OpenRead(strFileName)DoWhile fs.Read(b,0, b.Length)>0
temp.GetString(b,0, b.Length)Loop
fs.Close()
Resultado
FileStreamobviamente es más rápido en esta prueba. Se necesita un 50% más de tiempo para StreamReaderleer el archivo pequeño. Para el archivo grande, tomó un 27% adicional del tiempo.
StreamReaderestá buscando específicamente saltos de línea mientras FileStreamque no. Esto explicará parte del tiempo extra.
Recomendaciones
Dependiendo de lo que la aplicación necesite hacer con una sección de datos, puede haber un análisis adicional que requerirá un tiempo de procesamiento adicional. Considere un escenario en el que un archivo tiene columnas de datos y las filas están CR/LFdelimitadas. La StreamReaderfuncionaría abajo de la línea de texto en busca de la CR/LF, y luego la aplicación harían análisis adicional en busca de una ubicación específica de los datos. (¿Pensaste en String. SubString viene sin precio?)
Por otro lado, FileStreamlee los datos en fragmentos y un desarrollador proactivo podría escribir un poco más de lógica para usar la transmisión en su beneficio. Si los datos necesarios están en posiciones específicas en el archivo, este es ciertamente el camino a seguir, ya que mantiene el uso de memoria bajo.
FileStream es el mejor mecanismo para la velocidad pero requerirá más lógica.
publicstaticvoidReadFileToEnd(){try{//provide to reader your complete text file
using (StreamReader sr =newStreamReader("TestFile.txt")){String line = sr.ReadToEnd();Console.WriteLine(line);}}catch(Exception e){Console.WriteLine("The file could not be read:");Console.WriteLine(e.Message);}}
Para los novatos que encuentran estas cosas divertidas e interesantes, la forma más rápida de leer un archivo completo en una cadena en la mayoría de los casos (de acuerdo con estos puntos de referencia ) es mediante lo siguiente:
using (StreamReader sr =File.OpenText(fileName)){string s = sr.ReadToEnd();}//you then have to process the string
Sin embargo, el más rápido para leer un archivo de texto en general parece ser el siguiente:
using (StreamReader sr =File.OpenText(fileName)){string s =String.Empty;while((s = sr.ReadLine())!=null){//do what you have to here}}
Los comentarios llegan tarde, lo sé, pero están un poco confundidos con sus puntos de referencia aquí y en la página vinculada. Parece que solo prueba las velocidades de lectura y no se carga en una cadena completa. El segundo fragmento de código es leer una línea a la vez y no agregar nada, por lo que "hacer lo que tiene que hacer aquí" debería tener un generador de cadenas o una cadena para contener los datos. En ese momento, la memoria utilizada para agregar más datos cambiaría los resultados de la prueba. Por lo tanto, s generalmente tendrá el mismo tamaño suponiendo un archivo de ancho fijo, por lo que la memoria se configurará para el tamaño de una línea y no será necesario copiar los datos en la nueva memoria.
Charles Byrne
2
Puedes usar así
publicstaticstringReadFileAndFetchStringInSingleLine(string file){StringBuilder sb;try{
sb =newStringBuilder();
using (FileStream fs =File.Open(file,FileMode.Open)){
using (BufferedStream bs =newBufferedStream(fs)){
using (StreamReader sr =newStreamReader(bs)){string str;while((str = sr.ReadLine())!=null){
sb.Append(str);}}}}return sb.ToString();}catch(Exception ex){return"";}}
Hice una comparación entre un ReadAllText y StreamBuffer para un csv de 2Mb y parecía que la diferencia era bastante pequeña, pero ReadAllText parecía tomar la delantera de los tiempos necesarios para completar las funciones.
Respuestas:
Que tal
File.ReadAllText
:fuente
StreamReader.ReadToEnd
es más eficiente.StreamReader.ReadToEnd
es más eficiente queReadAllLines
. Lo cual es de esperar, ya que este último también divide el texto en líneas. Pero estamos hablando de un método diferente,ReadAllText
. De hecho, la respuesta que menciona muestra queReadAllText
solo llamaStreamReader.ReadToEnd
internamente.Una comparación de referencia del manejo de archivos C
File.ReadAllLines
vsStreamReader ReadLine
deEnfoque StreamReader
Como el
File.ReadAllText
enfoque ha sido sugerido por otros, también puede intentarlo más rápido (no he probado cuantitativamente el impacto en el rendimiento, pero parece ser más rápido queFile.ReadAllText
(ver la comparación a continuación)). Sin embargo, la diferencia en el rendimiento será visible solo en el caso de archivos más grandes.Comparación de File.Readxxx () vs StreamReader.Readxxx ()
Visualización del código indicativo través ILSpy he encontrado lo siguiente acerca de
File.ReadAllLines
,File.ReadAllText
.File.ReadAllText
- UtilizaStreamReader.ReadToEnd
internamenteFile.ReadAllLines
- También se usaStreamReader.ReadLine
internamente con la sobrecarga adicional de crear elList<string>
retorno como líneas de lectura y bucles hasta el final del archivo.Por lo tanto, ambos métodos son una capa adicional de conveniencia construida además
StreamReader
. Esto es evidente por el cuerpo indicativo del método.File.ReadAllText()
implementación como descompilada por ILSpyfuente
File.ReadAllText
?File.ReadAllText()
es simplemente una envolturaStreamReader.ReadToEnd()
. Supongo que la capa adicional debería funcionar un poco más lento queStreamReader.ReadToEnd()
.ReadAllText
solo es una envolturastreamReader.ReadToEnd();
?Aquí está la documentación de MSDN
fuente
Eche un vistazo al método File.ReadAllText ()
Algunas observaciones importantes:
fuente
string text = File.ReadAllText("Path");
tienes todo el texto en una variable de cadena. Si necesita cada línea individualmente, puede usar esto:fuente
fuente
@Cris lo siento. Esta es una cita
MSDN Microsoft
Metodología
En este experimento, se compararán dos clases. El
StreamReader
y laFileStream
clase serán dirigidos a leer dos archivos de 10K y 200K en su totalidad desde el directorio de la aplicación.Resultado
FileStream
obviamente es más rápido en esta prueba. Se necesita un 50% más de tiempo paraStreamReader
leer el archivo pequeño. Para el archivo grande, tomó un 27% adicional del tiempo.StreamReader
está buscando específicamente saltos de línea mientrasFileStream
que no. Esto explicará parte del tiempo extra.Recomendaciones
Dependiendo de lo que la aplicación necesite hacer con una sección de datos, puede haber un análisis adicional que requerirá un tiempo de procesamiento adicional. Considere un escenario en el que un archivo tiene columnas de datos y las filas están
CR/LF
delimitadas. LaStreamReader
funcionaría abajo de la línea de texto en busca de laCR/LF
, y luego la aplicación harían análisis adicional en busca de una ubicación específica de los datos. (¿Pensaste en String. SubString viene sin precio?)Por otro lado,
FileStream
lee los datos en fragmentos y un desarrollador proactivo podría escribir un poco más de lógica para usar la transmisión en su beneficio. Si los datos necesarios están en posiciones específicas en el archivo, este es ciertamente el camino a seguir, ya que mantiene el uso de memoria bajo.FileStream
es el mejor mecanismo para la velocidad pero requerirá más lógica.fuente
StreamReader.ReadToEnd
?bueno, la forma más rápida de significado con el menor código C # posible es probablemente esta:
fuente
Si desea elegir el archivo de la carpeta Bin de la aplicación, puede intentar lo siguiente y no olvide hacer un manejo de excepciones.
fuente
puedes usar :
fuente
fuente
Para los novatos que encuentran estas cosas divertidas e interesantes, la forma más rápida de leer un archivo completo en una cadena en la mayoría de los casos (de acuerdo con estos puntos de referencia ) es mediante lo siguiente:
Sin embargo, el más rápido para leer un archivo de texto en general parece ser el siguiente:
Frente a varias otras técnicas , ganó la mayor parte del tiempo, incluso contra el BufferedReader.
fuente
Puedes usar así
Espero que esto te ayudará.
fuente
puede leer un texto de un archivo de texto en una cadena de la siguiente manera también
fuente
fuente
Hice una comparación entre un ReadAllText y StreamBuffer para un csv de 2Mb y parecía que la diferencia era bastante pequeña, pero ReadAllText parecía tomar la delantera de los tiempos necesarios para completar las funciones.
fuente