Je voudrais créer un programme simple (en Java) qui édite des fichiers texte - en particulier un qui effectue l'insertion de morceaux de texte arbitraires à des positions aléatoires dans un fichier texte. Cette fonctionnalité fait partie d'un programme plus vaste que j'écris actuellement.
En lisant la description de Java.util.RandomAccessFile, il apparaît que toutes les opérations d'écriture effectuées au milieu d'un fichier remplaceraient en fait le contenu existant. C'est un effet secondaire que j'aimerais éviter (si possible).
Existe-t-il un moyen simple d'y parvenir?
Merci d'avance.
D'accord, cette question est assez ancienne, mais FileChannels existe depuis Java 1.4 et je ne sais pas pourquoi ils ne sont mentionnés nulle part quand il s'agit de remplacer ou d'insérer du contenu dans des fichiers. - FileChannels sont rapides, utilisez-les.
Voici un exemple (en ignorant les exceptions et d'autres choses):
public void insert(String filename, long offset, byte[] content) {
RandomAccessFile r = new RandomAccessFile(new File(filename), "rw");
RandomAccessFile rtemp = new RandomAccessFile(new File(filename + "~"), "rw");
long fileSize = r.length();
FileChannel sourceChannel = r.getChannel();
FileChannel targetChannel = rtemp.getChannel();
sourceChannel.transferTo(offset, (fileSize - offset), targetChannel);
sourceChannel.truncate(offset);
r.seek(offset);
r.write(content);
long newOffset = r.getFilePointer();
targetChannel.position(0L);
sourceChannel.transferFrom(targetChannel, newOffset, (fileSize - offset));
sourceChannel.close();
targetChannel.close();
}
Eh bien, non, je ne pense pas qu'il existe un moyen d'éviter d'écraser le contenu existant avec un seul appel standard Java IO API).
Si les fichiers ne sont pas trop volumineux, lisez tout le fichier dans une liste de tableaux (une entrée par ligne) et réécrivez les entrées ou insérez de nouvelles entrées pour les nouvelles lignes.
Remplacez ensuite le fichier existant par un nouveau contenu ou déplacez le fichier existant vers une sauvegarde et écrivez un nouveau fichier.
Selon le degré de sophistication des modifications, votre structure de données peut devoir changer.
Une autre méthode consisterait à lire les caractères du fichier existant lors de l'écriture dans le fichier modifié et à modifier le flux au fur et à mesure de sa lecture.
Si Java a un moyen de mapper les fichiers en mémoire, alors ce que vous pouvez faire est d'étendre le fichier à sa nouvelle longueur, de mapper le fichier, de déplacer tous les octets jusqu'à la fin pour faire un trou et écrire les nouvelles données dans le trou.
Cela fonctionne en C. Jamais essayé en Java.
Une autre façon, je viens de penser à faire de même, mais avec un accès aléatoire aux fichiers.
Utilisez une taille de tampon plus grande pour des performances plus rapides.
Vous pouvez utiliser le code suivant:
BufferedReader reader = null;
BufferedWriter writer = null;
ArrayList list = new ArrayList();
try {
reader = new BufferedReader(new FileReader(fileName));
String tmp;
while ((tmp = reader.readLine()) != null)
list.add(tmp);
OUtil.closeReader(reader);
list.add(0, "Start Text");
list.add("End Text");
writer = new BufferedWriter(new FileWriter(fileName));
for (int i = 0; i < list.size(); i++)
writer.write(list.get(i) + "\r\n");
} catch (Exception e) {
e.printStackTrace();
} finally {
OUtil.closeReader(reader);
OUtil.closeWriter(writer);
}
Je crois que la seule façon d'insérer du texte dans un fichier texte existant est de lire le fichier d'origine et d'écrire le contenu dans un fichier temporaire avec le nouveau texte inséré. Effacez ensuite le fichier d'origine et renommez le fichier temporaire en son nom d'origine.
Cette exemple se concentre sur l'insertion d'une seule ligne dans un fichier existant, mais peut-être encore utile pour vous.
Je ne sais pas s'il y a un moyen pratique de le faire autrement que
À propos de la cible: vous pouvez créer le nouveau contenu du fichier en mémoire, puis écraser l'ancien contenu du fichier si les fichiers traités ne sont pas si volumineux. Ou vous pouvez écrire le résultat dans un fichier temporaire.
La chose serait probablement plus facile à faire avec les flux, RandomAccessFile ne semble pas être destiné à être inséré au milieu (afaik). Vérifiez le tutoriel si vous en avez besoin.
S'il s'agit d'un fichier texte , Lisez le fichier existant dans StringBuffer et ajoutez le nouveau contenu dans le même StringBuffer maintenant vous pouvez écrire le SrtingBuffer sur le fichier. maintenant le fichier contient à la fois le texte existant et le nouveau.