¿Cómo leer un archivo completo en una cadena usando C #?


Respuestas:


373

Que tal File.ReadAllText:

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

3
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

Comparación de lectura de archivos

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 = new StreamReader(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.ReadAllText - Utiliza StreamReader.ReadToEndinternamente
  • 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

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
¿También te comparaste File.ReadAllText?
marc_s

2
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();?
Olivier Jacot-Descombes


6

Eche un vistazo al método File.ReadAllText ()

Algunas observaciones importantes:

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


6

string text = File.ReadAllText("Path");tienes todo el texto en una variable de cadena. Si necesita cada línea individualmente, puede usar esto:

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

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

4

@Cris lo siento. Esta es una cita MSDN Microsoft

Metodología

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 = 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

ingrese la descripción de la imagen aquí

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.


¿Pero que pasa StreamReader.ReadToEnd?
Owen Blacker

3

bueno, la forma más rápida de significado con el menor código C # posible es probablemente esta:

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

3

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.

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

3

puedes 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);
    }
}


2

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

Frente a varias otras técnicas , ganó la mayor parte del tiempo, incluso contra el BufferedReader.


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í

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 esto te ayudará.


0

puede leer un texto de un archivo de texto en una cadena de la siguiente manera también

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

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.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.