Remplacer la chaîne dans le fichier

Je cherche un moyen de remplacer une chaîne dans un fichier sans lire le fichier entier en mémoire. Normalement, j'utiliserais un lecteur et un écrivain, c'est-à-dire quelque chose comme ce qui suit:

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

Cependant, je veux faire le remplacement sur place, et ne pense pas que je puisse avoir un lecteur et un écrivain ouverts sur le même fichier simultanément. En outre, j'utilise Java 1.4, donc ne pas avoir accès à NIO, Scanner,etc.

Merci, N'

23
demandé sur Dónal 2010-06-30 12:36:14

2 réponses

Le remplacement"en place" n'est généralement pas possible pour les fichiers, sauf si le remplacement a exactement la même longueur que l'original. Sinon, le fichier devrait soit croître, mélangeant ainsi tous les octets ultérieurs "vers la droite", soit rétrécir. La façon courante de le faire est de lire le fichier, d'écrire le remplacement dans un fichier temporaire, puis de remplacer le fichier d'origine par le fichier temporaire.

Cela a également l'avantage que le fichier en question est à tout moment dans l'état d'origine ou dans l'état complètement remplacé, jamais entre les deux.

31
répondu Jakob Borg 2010-06-30 08:43:31

Remplacer quelque chose dans un fichier ou un flux nécessite un Writer ou OutputStream capable de supprimer et d'insérer des octets à n'importe quelle position. Une opération de remplacement peut être divisé en delete et {insérer[2]} opération.

En regardant L'API de OutputStream et Writer, Je ne trouve pas de méthodes appropriées. On pourrait utiliser OutputStream pour écrire des octets avec un décalage mais cela écrasera simplement le contexte existant. Donc, cela pourrait fonctionner pour le cas particulier, cet original et remplacement ont la même longueur.

Donc, en ce moment, je pense que, écrire les lignes éditées dans un fichier temporaire et remplacer le fichier orignal par le fichier temp par la suite est toujours la meilleure solution.

2
répondu Andreas_D 2010-06-30 09:55:34