web-dev-qa-db-fra.com

c # remplace la chaîne dans le fichier

String.Replace ne semble pas fonctionner correctement lors du remplacement d'une partie du contenu d'un fichier HTML. Par exemple, String.Replace remplace </body></html> avec blah blah blah </body></html> html> - notez que la deuxième balise de fermeture HTML n'est pas correctement fermée et apparaît donc lorsque la page est rendue dans le navigateur par l'utilisateur.

Quelqu'un sait pourquoi cela ne fonctionne pas comme prévu?

StreamReader sr = fi.OpenText;
String fileContents = sr.ReadToEnd();
sr.close();
fileContents = fileContents.Replace("<body>", "<body onload='jsFx();' />");
fileContents = fileContents.Replace("</body>","blah blah blah </body>");

StreamWriter sw = new StreamWriter(fi.OpenWrite());
sw.WriteLine(contents);
sw.close();
23
Joey

Je pourrais réécrire votre morceau de code comme ceci:

var fileContents = System.IO.File.ReadAllText(@"C:\File.html");

fileContents = fileContents.Replace("<body>", "<body onload='jsFx();' />"); 
fileContents = fileContents.Replace("</body>","blah blah blah </body>"); 

System.IO.File.WriteAllText(@"C:\File.html", fileContents);

Je dois noter que cette solution convient aux fichiers de taille raisonnable. Selon le matériel, tout ce qui est inférieur à quelques dizaines de Mo. Il charge tout le contenu en mémoire. Si vous avez un fichier vraiment volumineux, vous devrez peut-être le diffuser sur quelques centaines de Ko à la fois pour éviter une OutOfMemoryException. Cela rend les choses un peu plus compliquées, car vous devez également vérifier la coupure entre chaque morceau pour voir si vous divisez votre chaîne de recherche.

56
Nate

Il n'y a rien de mal avec string.Replace Ici.

Ce qui est faux, c'est que vous écrasez le fichier sans le tronquer ... donc si vous avez changé votre code d'écriture pour juste

sw.WriteLine("Start");

vous verriez "Démarrer", puis le reste du fichier.

Je vous recommande d'utiliser File.ReadAllText et File.WriteAllText à la place (prenez le chemin du FileInfo). De cette façon:

  • Il remplacera complètement le fichier, au lieu de simplement écraser
  • Vous n'avez pas à vous soucier de fermer correctement le lecteur/l'écrivain/le flux (ce que vous ne faites pas maintenant - si une exception se produit, vous laissez le lecteur ou l'écrivain ouvert)

Si vous vraiment voulez utiliser les méthodes FileInfo, utilisez FileInfo.Open(FileMode.Create) qui tronquera le fichier.

14
Jon Skeet