2010-12-02 10 views
23

String.Replace no parece funcionar correctamente al reemplazar una parte del contenido de un archivo HTML. Por ejemplo, String.Replace reemplaza </body></html> con blah blah blah </body></html> html> - observe que la segunda etiqueta de cierre de HTML no se cierra correctamente y, por lo tanto, aparece cuando el usuario muestra la página en el navegador.C# replace string dentro del archivo

¿Alguien sabe por qué no está funcionando como se esperaba?

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

¿Puede proporcionar un ejemplo de su archivo fuente? El código que ha enviado * debe * funcionar como usted lo describe. No veo ninguna razón por la que obtendría un bit 'html>' extra ... – Nate

+1

¿Hay alguna posibilidad de que esa etiqueta extraña ya esté en el archivo de entrada? También noté en el ejemplo del código que tiene una etiqueta de cuerpo cerrado automático, ¿es así? – MrEyes

+0

Nate - gracias por la rápida respuesta y limpieza. No código real, pero lo suficientemente cerca como para transmitir mi punto. – Joey

Respuesta

12

No hay nada malo con string.Replace aquí.

Qué es mal es que se desea sobreescribir el archivo pero no truncar ... así que si ha cambiado su código de escritura a solo

sw.WriteLine("Start"); 

verías "Inicio" y luego el resto del archivo.

Yo recomendaría que use File.ReadAllText y File.WriteAllText (tome la ruta desde FileInfo). De esa manera:

  • Se sustituirá completamente el archivo, en lugar de sobrescribir
  • Usted no necesita preocuparse de cerrar el lector/grabador/corriente adecuada (que no se están haciendo ahora - si un excepción ocurre, estás dejando que el lector o escritor abierta)

Si realmente desea utilizar los métodos FileInfo, utilice FileInfo.Open(FileMode.Create) que se trunque el archivo.

+0

Buena captura ..... – Nate

+0

Jon - Gracias por la respuesta rápida y la explicación. Explique por qué no necesitaría cerrar el lector/escritor/transmisión en el ejemplo anterior. - Me doy cuenta de que el código que proporcioné está sucio. No se copia del desarrollo, sino que solo trata de sacar mi pregunta. – Joey

+0

@Joey: solo los cierras si no hay excepciones. Debería usar declaraciones 'using' para deshacerse de ellas pase lo que pase, es el equivalente a try/finally. –

52

podría reescribir su poco de código como este:

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

Debo señalar que esta solución está muy bien para archivos de tamaño razonable. Dependiendo del hardware, cualquier cosa en unas pocas decenas de MB. Carga todo el contenido en la memoria. Si tiene un archivo realmente grande, puede necesitar transmitirlo a través de unos cientos de KB a la vez para evitar una OutOfMemoryException. Eso hace que las cosas sean un poco más complicadas, ya que también necesitarías verificar el descanso entre cada fragmento para ver si dividir tu cadena de búsqueda.