2010-12-02 7 views
23

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> par blah blah blah </body></html> html> - notez que la deuxième balise de fermeture HTML n'est pas correctement fermée et qu'elle apparaît par conséquent lorsque la page est rendue dans le navigateur par l'utilisateur.C# remplace la chaîne dans le fichier

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(); 
+1

Pouvez-vous fournir un exemple de votre fichier source? Le code que vous avez soumis * devrait * fonctionner comme vous le décrivez. Je ne vois pas pourquoi vous auriez un bit "html>" supplémentaire ... – Nate

+1

Y a-t-il une chance que cette balise soit déjà dans le fichier d'entrée? Aussi, je remarque dans l'exemple de code que vous avez un tag de corps auto-fermé, n'est-ce pas? – MrEyes

+0

Nate - merci pour la réponse rapide et le nettoyage. Pas de code réel, mais assez proche pour faire passer mon message. – Joey

Répondre

12

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

Quelle est mal est que vous écrasez le fichier, mais pas tronquer ... donc si vous avez changé votre code d'écriture juste

sw.WriteLine("Start"); 

vous verriez « Démarrer » puis la reste du fichier.

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

  • Il remplacera complètement le fichier, au lieu d'écraser
  • Vous n'avez pas à vous soucier de fermer le lecteur/graveur/flux correctement (que vous n'êtes pas en ce moment - si un exception se produit, vous quittez le lecteur ou écrivain ouvert)

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

+0

Bonne prise ..... – Nate

+0

Jon - Merci pour la réponse rapide et l'explication. Veuillez expliquer pourquoi je n'aurais pas besoin de fermer le lecteur/enregistreur/flux dans l'exemple ci-dessus. - Je réalise que le code que j'ai fourni est sale. Ce n'est pas une copie du développement, mais plutôt d'essayer de sortir ma question. – Joey

+0

@Joey: Vous ne les fermez que s'il n'y a pas d'exception. Vous devriez utiliser les instructions 'using' pour les éliminer quoi qu'il arrive - c'est l'équivalent d'essayer/finalement. –

52

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 souligner que cette solution est très bien pour les fichiers de taille raisonnable. Selon le matériel, n'importe quoi sous quelques dizaines de MB. Il charge le contenu entier en mémoire. Si vous avez un fichier très volumineux, vous devrez peut-être le diffuser en quelques centaines de Ko à la fois pour éviter une exception OutOfMemoryException. Cela rend les choses un peu plus compliquées, puisque vous devez également vérifier la pause entre chaque morceau pour voir si vous divisez votre chaîne de recherche.

Questions connexes