2010-06-30 17 views
23

Estoy buscando una manera de reemplazar una cadena en un archivo sin leer todo el archivo en la memoria. Normalmente me gustaría utilizar un lector y escritor, es decir, algo así como lo siguiente:Reemplazar cadena en el archivo

public static void replace(String oldstring, String newstring, File in, File out) 
    throws IOException { 

    BufferedReader reader = new BufferedReader(new FileReader(in)); 
    PrintWriter writer = new PrintWriter(new FileWriter(out)); 
    String line = null; 
    while ((line = reader.readLine()) != null) 
     writer.println(line.replaceAll(oldstring,newstring)); 

    // I'm aware of the potential for resource leaks here. Proper resource 
    // handling has been omitted in the interest of brevity 
    reader.close(); 
    writer.close(); 
} 

Sin embargo, quiero hacer la sustitución en el lugar, y no creo que puedo tener un lector y escritor abierta en el mismo archivo al mismo tiempo Además, estoy usando Java 1.4, por lo dont't tiene acceso a NIO, escáner, etc.

Gracias, Don

+1

Solo para tu información, eres consciente de que 'replaceAll' está basado en expresiones regulares, ¿no? Si solo quieres hacer un reemplazo literal de cadena recta (como sugieren los nombres de tus parámetros formales), puedes usar el método 'replace (CharSequence, CharSequence)' en su lugar. – polygenelubricants

+0

¿Qué tal escribir en un archivo temporal y luego reemplazar el original? – InsertNickHere

Respuesta

31

"En lugar de" reemplazar por lo general no es posible en los archivos, a menos que la sustitución es exactamente la misma longitud que el original. De lo contrario, el archivo tendría que crecer, por lo tanto, reorganizar todos los bytes posteriores "hacia la derecha" o reducirlo. La forma más común de hacer esto es leer el archivo, escribir el reemplazo en un archivo temporal y luego reemplazar el archivo original con el temporal.

Esto también tiene la ventaja de que el archivo en cuestión está en todo momento en el estado original o en el estado completamente reemplazado, nunca en el medio.

+3

+1 Para una respuesta bien explicada – naikus

2

Reemplazar algo en un archivo o secuencia requiere un Writer o OutputStream que sea capaz de eliminar e insertar bytes en cualquier posición. Una operación de reemplazo se puede dividir en eliminar y insertar operación.

En cuanto a la API de OutputStream y Writer no puedo encontrar los métodos adecuados. Se podría usar OutputStream para escribir bytes con un desplazamiento, pero esto simplemente sobrescribirá el contexto existente. Por lo tanto, podría funcionar para el caso especial, que el original y el reemplazo tienen la misma longitud.

Creo que escribir las líneas editadas en un archivo temporal y reemplazar el archivo orignal con el archivo temporal después sigue siendo la mejor solución.

Cuestiones relacionadas