8
votes

Java - Supprimer la ligne du fichier texte en écrasant tout en le lisant

J'essaie de supprimer une ligne de texte à partir d'un fichier texte sans copier dans un fichier temporaire. J'essaie de le faire en utilisant un imprimeur et un scanner et d'avoir des traverser le fichier en même temps, l'auteur écrit ce que le scanner lit et écrase chaque ligne avec la même chose, jusqu'à ce que cela puisse atteindre la ligne que je souhaite effacer. Ensuite, je avance le scanner mais pas l'écrivain et continue comme avant. Voici le code:

mais d'abord, les paramètres: mes noms de fichiers sont des numéros, cela lirait donc 1txt ou 2.txt, etc., et donc F Spécifie le nom du fichier. Je le convertit sur une chaîne dans le constructeur pour un fichier. INT N est l'index de la ligne que je veux supprimer. P>

public void deleteLine(int f, int n){
 try{
 Scanner reader = new Scanner(new File(f+".txt")); 
 PrintWriter writer = new PrintWriter(new FileWriter(new File(f+".txt")),false); 
 for(int w=0; w<n; w++)
   writer.write(reader.nextLine()); 
 reader.nextLine(); 
 while(reader.hasNextLine())
   writer.write(reader.nextLine());
 } catch(Exception e){
   System.err.println("Enjoy the stack trace!");
   e.printStackTrace();
 }
}


3 commentaires

Pourquoi ne pas utiliser un fichier temporaire? Quelle est votre aversion à cela?


@ Hovercraft pleine d'anguilles à dire la vérité, je ne sais pas vraiment comment, et tout ce qui copie de l'arrière-plan semble assez inefficace. Je devrais supprimer le fichier d'origine et renommer le temporaire que pour le remplacer, oui? Ne serait-il pas plus facile et plus efficace de simplement lire et écrire ledit fichier en même temps?


Ce n'est pas plus facile, c'est faux. S'il vous plaît voir la réponse.


3 Réponses :


1
votes

@shelley: Vous ne pouvez pas faire ce que vous essayez de faire et de plus, vous ne devriez pas. Vous devriez lire le fichier et écrire dans un fichier temporaire pour plusieurs raisons, pour une, il est possible de le faire de cette façon (par opposition à ce que vous essayez de faire) et pour un autre, si le processus est corrompu, vous pourriez Bale Sans perte du fichier d'origine. Vous pouvez maintenant mettre à jour un emplacement spécifique d'un fichier à l'aide d'un fichier randomAccessfile, mais cela se fait généralement (dans mon expérience) lorsque vous avez affaire à des enregistrements de taille fixe plutôt que des fichiers texte typiques.


2 commentaires

C'est un bon point. Votre conseil est pris. Une autre question: créer un fichier temporaire, j'utiliserais Createetempfile ou juste le constructeur avec un nom de fichier différent? (Désolé si cela semble une question idiote; je suis novice avec des fichiers d'E / S avec des fichiers.)


@Shelley: Avez-vous traversé les tutoriels Java, la section d'E / S? Sinon, je vous conseille d'avoir un look: E / S de base < / a>



2
votes

Vous ne pouvez pas le faire de cette façon. FileWriter ne peut que ajouter à un fichier, plutôt que d'écrire au milieu de celui-ci - vous avez besoin de soin de l'accessoire si vous souhaitez écrire au milieu. Ce que vous faites maintenant - vous remplacez le fichier la première fois que vous écrivez (et il est vide - c'est pourquoi vous obtenez l'exception). Vous pouvez créer un FileWriter avec APPEND DRAPORT défini sur True - mais de cette façon, vous admettez un fichier plutôt que d'écrire au milieu de celui-ci.

Je recommanderais vraiment d'écrire dans un nouveau fichier, puis de le renommer à la fin.


1 commentaires

Oui, 1+ pour recommander d'écrire dans un nouveau fichier et de le renommer.



24
votes

7 commentaires

@AIOOBE: Mais pourquoi, quel est l'avantage, quand sa raison principale pour le faire, la manière originale était due à l'ignorance plutôt que de besoin? Et si il / elle veut insérer du texte plus tard plus grand que le texte supprimé?


L'avantage le plus évident est qu'il ne nécessite pas deux fois l'espace disque. Si le fichier est vraiment important, il peut ne pas être possible d'avoir deux copies même temporairement.


@aioobe: 500 lignes de texte sont-elles qualifiées comme vraiment grandes? La raison pour laquelle je demande est que je crains que votre réponse soit induire en erreur quelqu'un qui est tout à fait nouveau à Java en pensant que c'est la meilleure réponse à sa situation. Je crois que ce n'est pas le cas.


Dépend évidemment des longueurs des lignes. N'est-ce pas ;-) Mise à jour de la réponse quand même.


@aioobe je l'apprécie;) @ hovercraft plein d'anguilles bien, ma justification était l'efficacité, mais j'avoue que je suis un peu nouveau à Java. Je vais le faire avec le fichier temporaire, la façon dont cela devrait être fait. Néanmoins ... pourriez-vous expliquer un peu plus en détail pourquoi je fais la façon dont je tentais, c'est tort si cela est possible et prend moins d'espace? Une explication m'aiderait grandement dans ma quête de la connaissance de Java :-)


@Shelley: Je ne connais pas d'avantages de vitesse relative d'une technique sur l'autre, mais comme Aioobe, un RAF présente des avantages de la taille, alors qu'il y a des avantages de sécurité définis de laisser le fichier d'origine intact jusqu'à ce que le processus soit Complétez, et même peut-être ensuite renommer le fichier d'origine afin qu'il puisse être sauvegardé l'aa sauvegarde avant de donner le nom d'origine du nom d'origine.


@AIOOBE: Merci pour la modification et l'accord. Changé -1 vote à +1.