Comment lire un fichier entier dans une chaîne en utilisant C #?

215

Quelle est la façon la plus rapide de lire un fichier texte dans une variable chaîne?

Je comprends que cela peut être fait de plusieurs façons, telles que la lecture d'octets individuels, puis la conversion en chaîne. Je cherchais une méthode avec un codage minimal.

Shamim Hafiz
la source
Consultez ce stackoverflow.com/questions/2855335/…
Sandeep GB

Réponses:

374

Que diriez-vous File.ReadAllText:

string contents = File.ReadAllText(@"C:\temp\test.txt");
marc_s
la source
3
Mais ce n'est pas la meilleure fonction à utiliser. Comme le souligne Devendra D. Chavan dans sa réponse, StreamReader.ReadToEndest plus efficace.
Owen Blacker
40
@OwenBlacker Cela dépend si "le plus rapide" signifie "le moins de temps pour exécuter" ou "le moins de temps pour comprendre".
bonh
2
File.ReadAllText est définitivement le plus simple à utiliser, mais comme le souligne "Devendra D. Chavan", ce n'est pas le plus rapide. Donc, si vous lisez de petits fichiers, ce serait un meilleur choix d'utiliser File.ReadAllText.it dépend vraiment de la taille des fichiers texte que vous lisez.
Mana
Pour lire à partir du serveur, vérifiez cela , l'espoir aide quelqu'un.
shaijut
1
@OwenBlacker - êtes-vous sûr? Le benchmark montre que StreamReader.ReadToEndc'est plus efficace que ReadAllLines. Ce qui est normal, car ce dernier divise également le texte en lignes. Mais nous parlons d'une autre méthode, ReadAllText. En effet, la réponse que vous mentionnez montre que cela ReadAllTextne fait qu'appeler en StreamReader.ReadToEndinterne.
Ed Avis
170

Une comparaison de référence de File.ReadAllLinesvs à StreamReader ReadLinepartir de la gestion des fichiers C #

Comparaison de lecture de fichiers

Résultats. StreamReader est beaucoup plus rapide pour les fichiers volumineux de plus de 10 000 lignes, mais la différence pour les fichiers plus petits est négligeable. Comme toujours, planifiez différentes tailles de fichiers et utilisez File.ReadAllLines uniquement lorsque les performances ne sont pas critiques.


Approche StreamReader

Comme l' File.ReadAllTextapproche a été suggérée par d'autres, vous pouvez également essayer plus rapidement (je n'ai pas testé quantitativement l'impact sur les performances, mais il semble être plus rapide que File.ReadAllText(voir comparaison ci-dessous)). La différence de performances ne sera visible que dans le cas de fichiers plus volumineux.

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


Comparaison de File.Readxxx () et StreamReader.Readxxx ()

Affichage du code indicatif par ILSpy J'ai trouvé ce qui suit à propos File.ReadAllLines, File.ReadAllText.

  • File.ReadAllText - Utilise en StreamReader.ReadToEndinterne
  • File.ReadAllLines - Utilise également en StreamReader.ReadLineinterne avec la surcharge supplémentaire de créer le List<string>retour en tant que lignes de lecture et de boucler jusqu'à la fin du fichier.


Donc, les deux méthodes sont une couche supplémentaire de commodité construite sur StreamReader. Cela est évident par le corps indicatif de la méthode.

File.ReadAllText() implémentation décompilée par 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
la source
2
Avez-vous également comparé File.ReadAllText?
marc_s
2
ILSpy suggère qu'il File.ReadAllText()s'agit simplement d'un wrapper StreamReader.ReadToEnd(). Je suppose que la couche supplémentaire devrait fonctionner légèrement plus lentement que StreamReader.ReadToEnd().
Devendra D. Chavan,
Très bonne réponse. Peut-être un peu d'explication pour ceux qui recherchent juste le correctif, mais cela mérite au moins autant de votes que la réponse choisie.
Sandy Gifford
@Devendra D. Chavan: Hors sujet, mais où puis-je trouver des références ou de la documentation pour ILSpy?
Viral Jain
1
Vous pouvez également trouver le code ici: referencesource.microsoft.com/#mscorlib/system/io/… . Ce que je ne comprends pas, c'est pourquoi il y a cette différence de vitesse importante si ReadAllTextc'est juste un wrapper pour streamReader.ReadToEnd();?
Olivier Jacot-Descombes
7

Jetez un œil à la méthode File.ReadAllText ()

Quelques remarques importantes:

Cette méthode ouvre un fichier, lit chaque ligne du fichier, puis ajoute chaque ligne en tant qu'élément d'une chaîne. Il ferme ensuite le fichier. Une ligne est définie comme une séquence de caractères suivie d'un retour chariot ('\ r'), d'un saut de ligne ('\ n') ou d'un retour chariot immédiatement suivi d'un saut de ligne. La chaîne résultante ne contient pas le retour chariot final et / ou le saut de ligne.

Cette méthode tente de détecter automatiquement l'encodage d'un fichier en fonction de la présence de marques d'ordre d'octets. Les formats d'encodage UTF-8 et UTF-32 (big-endian et little-endian) peuvent être détectés.

Utilisez la surcharge de la méthode ReadAllText (String, Encoding) lors de la lecture de fichiers pouvant contenir du texte importé, car les caractères non reconnus peuvent ne pas être lus correctement.

Le descripteur de fichier est garanti d'être fermé par cette méthode, même si des exceptions sont levées

sll
la source
6

string text = File.ReadAllText("Path");vous avez tout le texte dans une variable de chaîne. Si vous avez besoin de chaque ligne individuellement, vous pouvez utiliser ceci:

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

@Cris désolé .C'est une citation MSDN Microsoft

Méthodologie

Dans cette expérience, deux classes seront comparées. Le StreamReaderet la FileStreamclasse seront dirigés pour lire deux fichiers de 10K et 200K dans leur intégralité à partir du répertoire de l'application.

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

Résultat

entrez la description de l'image ici

FileStreamest évidemment plus rapide dans ce test. Il faut 50% de temps supplémentaire pour StreamReaderlire le petit fichier. Pour le gros fichier, cela a pris 27% de temps supplémentaire.

StreamReaderrecherche spécifiquement les sauts de ligne alors qu'il FileStreamn'en a pas Cela représentera une partie du temps supplémentaire.

Recommandations

Selon ce que l'application doit faire avec une section de données, une analyse supplémentaire peut nécessiter un temps de traitement supplémentaire. Considérez un scénario dans lequel un fichier a des colonnes de données et les lignes sont CR/LFdélimitées. Le StreamReadertravaillerait sur la ligne de texte à la recherche duCR/LF , puis l'application effectuerait une analyse supplémentaire à la recherche d'un emplacement spécifique des données. (Pensiez-vous que String. SubString est livré sans prix?)

D'un autre côté, le FileStreamlit les données en morceaux et un développeur proactif pourrait écrire un peu plus de logique pour utiliser le flux à son avantage. Si les données nécessaires se trouvent dans des positions spécifiques dans le fichier, c'est certainement la voie à suivre car cela réduit l'utilisation de la mémoire.

FileStream est le meilleur mécanisme de vitesse mais prendra plus de logique.

MinhVuong
la source
Mais qu'en est-il StreamReader.ReadToEnd?
Owen Blacker
3

eh bien le moyen le plus rapide qui signifie avec le moins de code C # possible est probablement celui-ci:

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

si vous souhaitez choisir un fichier dans le dossier Bin de l'application, vous pouvez essayer de suivre et n'oubliez pas de gérer les exceptions.

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

vous pouvez utiliser :

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

Pour les noobs qui trouvent ce truc amusant et intéressant, le moyen le plus rapide de lire un fichier entier dans une chaîne dans la plupart des cas ( selon ces repères ) est le suivant:

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

Cependant, le plus rapide pour lire un fichier texte dans son ensemble semble être le suivant:

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

Confronté à plusieurs autres techniques , il l'emportait la plupart du temps, notamment contre le BufferedReader.


la source
Le commentaire est en retard je sais, mais un peu confus sur vos repères ici et sur la page liée. Il semble tester uniquement les vitesses de lecture et ne pas charger dans une chaîne entière. Le deuxième extrait de code lit une ligne à la fois et ne fait aucun ajout, donc le "faites ce que vous avez à faire ici" devrait avoir un générateur de chaîne ou une chaîne pour contenir les données. À quel point la mémoire utilisée pour ajouter plus de données changerait les résultats du test. Donc, s sera généralement de la même taille en supposant un fichier à largeur fixe, de sorte que la mémoire sera définie pour la taille d'une ligne et les données n'auront pas besoin d'être copiées dans une nouvelle mémoire.
Charles Byrne
2

Vous pouvez utiliser comme ça

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

J'espère que ceci vous aidera.

Amit Kumawat
la source
0

vous pouvez lire un texte d'un fichier texte dans une chaîne comme suit également

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

                  }
              }
          }
      }
    }
GEAI
la source
0

J'ai fait une comparaison entre un ReadAllText et StreamBuffer pour un csv de 2 Mo et il semblait que la différence était assez petite mais ReadAllText semblait prendre le dessus sur le temps nécessaire pour terminer les fonctions.

Hatitye Chindove
la source