Précédent   Forum des professionnels en informatique > Java > Général Java > Langage
Langage Forum d'entraide sur le langage Java et autres langages pour la JVM : syntaxe, POO, conventions, API standard. Avant de poster -> FAQ Java
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 06/02/2012, 22h02   #1
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
Par défaut Juste supprimer un fichier texte

Bonjour à tous,

J'ai vraiment du mal sur ce coup là.

En gros je veux modifier un fichier texte.
Donc je l'ouvre et je le lit ligne par ligne.

Chaque ligne lue est modifiée, et écrite dans un nouveau fichier texte.

Je me retrouve donc avec mon fichier d'origine qui a juste été lu, et avec un nouveau fichier dont le contenu est différent du premier.

A ce niveau là, le but est de supprimer le fichier d'origine puis de renommer le nouveau avec le nom du premier.

Et c'est la suppression qui bloque. J'ai l'impression que lorsque j'ouvre le fichier d'origine pour le lire, Windows crée un processus qui ne se fermera pas ensuite, m’empêchant ainsi de le supprimer.

J'imagine que je dois mal fermé mes bufferedReaders ou autres...

Et ça n'est pas systématique! Parfois il suffit d'attendre assez longtemps pour que la suppression se fasse, mais ça ralenti mon appli méchamment.

Voici mon code bien simplifié:

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 
private void ecrireInformations(String fichier) throws IOException
{
 
	FileWriter writer = null;
	BufferedWriter output = null;
	BufferedReader reader = null;
	try
	{
 
		File fic = new File(fichier);
		FileInputStream fis = new FileInputStream(fichier);
		InputStreamReader isr = new InputStreamReader(fis);
		reader = new BufferedReader(isr);
		writer = new FileWriter("." + File.separator + name, true);
		output = new BufferedWriter(writer);
 
		while (reader.ready())
		{
			String line = reader.readLine();
 
			output.newLine();
			output.write(line + " exemple");
 
		}
 
		fis.close();
		isr.close();
		reader.close();
		output.flush();
		output.close();
		writer.close();
 
                //C'est là que ça mouline tant que le fichier n'est pas débloqué.
		while (fic.exists())
		{
			secureDelete(fic);
		}
 
 
		File source = new File("." + File.separator + name);
		source.renameTo(fic);
 
	}
	catch (FileNotFoundException e)
	{
		e.printStackTrace();
	}
}
 
public static void secureDelete(File file) throws IOException
{
	if (file.exists())
	{
		long length = file.length();
		SecureRandom random = new SecureRandom();
		RandomAccessFile raf = new RandomAccessFile(file, "rws");
		raf.seek(0);
		raf.getFilePointer();
		byte[] data = new byte[64];
		int pos = 0;
		while (pos < length)
		{
			random.nextBytes(data);
			raf.write(data);
			pos += data.length;
		}
		raf.close();
		file.delete();
	}
}
Où ai-je foiré?

Merci d'avance!
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 09h35   #2
Modérateur
 
Homme Mathieu
Ingénieur développement logiciels
Inscription : avril 2004
Messages : 855
Détails du profil
Informations personnelles :
Nom : Homme Mathieu
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : avril 2004
Messages : 855
Points : 1 164
Points : 1 164
Pourquoi écris-tu des données dans le fichier à supprimer ?
Mathieu.J est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 09h40   #3
Membre Expert
 
Avatar de wax78
 
Homme Renaud Warnotte
Développeur Java
Inscription : août 2006
Messages : 1 128
Détails du profil
Informations personnelles :
Nom : Homme Renaud Warnotte
Âge : 31
Localisation : Belgique

Informations professionnelles :
Activité : Développeur Java
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2006
Messages : 1 128
Points : 1 807
Points : 1 807
Envoyer un message via MSN à wax78
Parce que tu n'as pas bien lu Il ecrit dans une nouveau fichier qui va remplacer l'ancien.

Citation:
Envoyé par docv266 Voir le message
Chaque ligne lue est modifiée, et écrite dans un nouveau fichier texte.

Je me retrouve donc avec mon fichier d'origine qui a juste été lu, et avec un nouveau fichier dont le contenu est différent du premier.

A ce niveau là, le but est de supprimer le fichier d'origine puis de renommer le nouveau avec le nom du premier.
wax78 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 09h51   #4
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
C'est ça.

Il n'y a pas moyen de modifier directement un fichier texte n'est-ce pas? Il faut absolument en écrire un nouveau?
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 10h21   #5
Modérateur
 
Homme Mathieu
Ingénieur développement logiciels
Inscription : avril 2004
Messages : 855
Détails du profil
Informations personnelles :
Nom : Homme Mathieu
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : avril 2004
Messages : 855
Points : 1 164
Points : 1 164
Citation:
Envoyé par wax78 Voir le message
Parce que tu n'as pas bien lu Il ecrit dans une nouveau fichier qui va remplacer l'ancien.
Si j'ai bien lu, je parlais de la méthode secureDelete(...) et des 64 bytes aléatoires écris dans ce fichier...
Mathieu.J est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 10h23   #6
Expert Confirmé Sénior
 
Inscription : septembre 2004
Messages : 5 101
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 101
Points : 7 027
Points : 7 027
Citation:
Envoyé par wax78 Voir le message
Parce que tu n'as pas bien lu Il ecrit dans une nouveau fichier qui va remplacer l'ancien.
Lis son code.

Citation:
Envoyé par wax78 Voir le message
C'est ça.
Non ce n'est pas ça. Ta méthode "secureDelete()" (?? What the heck, au passage ??) écrit des données aléatoires dans le fichier que tu cherches à supprimer. Pourquoi ?

Note : je ne dis pas que le problème vient de là. Je ne vois pas l'intérêt, mais en principe ça ne devrait pas gêner la suppression du fichier.

Citation:
Envoyé par wax78 Voir le message
Il n'y a pas moyen de modifier directement un fichier texte n'est-ce pas? Il faut absolument en écrire un nouveau?
Bah disons que si le fichier n'est pas trop gros, il est possible de travailler avec une copie en mémoire au lieu de sur disque. Mais ça revient au même, oui.
thelvin est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/02/2012, 10h30   #7
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
Ma fonction secureDelete (qui n'est pas de moi d'ailleurs) peut surprendre oui.

En fait au fil de mes recherches pour arriver à supprimer ce fichier, j'ai testé plusieurs solutions.
Cette fonction est celle qui marchait le mieux au moment de mes tests mais je vais la remplacer par un bon vieux File.delete qui sera amplement suffisant une fois l'erreur trouvée.

Je rappelle que je ne peux pas supprimer le fichier d'origine (celui qui est juste lu) , il me faut attendre que le fichier soit libéré.
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 10h48   #8
Modérateur
 
Homme Mathieu
Ingénieur développement logiciels
Inscription : avril 2004
Messages : 855
Détails du profil
Informations personnelles :
Nom : Homme Mathieu
Localisation : France

Informations professionnelles :
Activité : Ingénieur développement logiciels

Informations forums :
Inscription : avril 2004
Messages : 855
Points : 1 164
Points : 1 164
Au passage

Ne me parait pas correct pour lire ton fichier ligne par ligne.
ready() ne retourne pas une information de "reste à lire", mais de "prêt à lire".


==> http://java.developpez.com/faq/java/...eLigneParLigne
Mathieu.J est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 12h08   #9
Rédacteur/Modérateur
 
Avatar de adiGuba
 
Homme
Développeur Java/Web
Inscription : avril 2002
Messages : 12 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Corse (Corse)

Informations professionnelles :
Activité : Développeur Java/Web
Secteur : Transports

Informations forums :
Inscription : avril 2002
Messages : 12 460
Points : 19 447
Points : 19 447
Salut,


+1 avec Mathieu.J : il vaut mieux éviter de se baser sur la méthode ready() de Reader (tout comme available() d'InputStream d'ailleurs). Ces méthodes peuvent renvoyer un résultat négatif avant la fin du fichier... il est préférable de simplement lire jusqu'à la fin du flux...


En plus c'est encore plus simple :
Code :
1
2
3
4
    String line;
    while ( (line = reader.readLine()) != null ) {
        ...
    }




Citation:
Envoyé par docv266 Voir le message
Voici mon code bien simplifié
Et tu rencontres le problèmes même avec ce code "simplifié" ?
Tu es sûr que le fichier n'est pas utilisé par un autre processus ?

Sinon quelques conseil :
  • évites de multiplier les flux et englobe-les (ca évitera de manipuler 5 variables pour un même flux :
    Code :
    BufferedWriter writer = new BufferedWriter(new FileWriter("." + File.separator + name, true));
  • essayes de rester cohérent dans tes choix : dans un cas tu ouvres le fichier un InputStreamReader , dans l'autre tu utilises directement un FileWriter ? Pourquoi ne pas utiliser un FileReader ? ou un OutputStreamWriter ? Au passage attention à l'encodage que tu ne spécifie pas !

  • Utilises des try/finally pour libérer tes flux au plus tôt !


a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java Présentation de Java SE 7 (commentaires)
adiGuba est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 12h41   #10
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
Merci pour tous ces conseils, je vais appliquer ça ce soir.

Je dois avouer que je me mélange un peu les pinceaux avec les flux.
Il y a 3 couches de flux et plusieurs options possibles.

Il faut absolument que je m'y intéresse vraiment et que j’arrête de recopier bêtement des lignes de codes trouvées sur Google...

Je vous tiens au courant des mes tests de ce soir.
Merci!
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 13h46   #11
Membre Expert
 
Avatar de wax78
 
Homme Renaud Warnotte
Développeur Java
Inscription : août 2006
Messages : 1 128
Détails du profil
Informations personnelles :
Nom : Homme Renaud Warnotte
Âge : 31
Localisation : Belgique

Informations professionnelles :
Activité : Développeur Java
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2006
Messages : 1 128
Points : 1 807
Points : 1 807
Envoyer un message via MSN à wax78
Citation:
Envoyé par thelvin Voir le message
Non ce n'est pas ça. Ta méthode "secureDelete()" (?? What the heck, au passage ??) écrit des données aléatoires dans le fichier que tu cherches à supprimer. Pourquoi ?
Wipping ou shred file ?
wax78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 07/02/2012, 13h53   #12
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
On est un peu HS là mais effectivement c'est le but de la fonction secureDelete.
Ça fait du wipping. En gros on ne se contente pas de supprimer, on écrit par dessus pour être sûr que ça ne sera pas récupéré.

Dans mon cas ce n'est absolument pas nécessaire.
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 14h14   #13
Expert Confirmé Sénior
 
Inscription : septembre 2004
Messages : 5 101
Détails du profil
Informations forums :
Inscription : septembre 2004
Messages : 5 101
Points : 7 027
Points : 7 027
Citation:
Envoyé par wax78 Voir le message
Wipping ou shred file ?
Ouais, j'y ai repensé. Je ne l'ai pas vu tout de suite, car je ne fais pas du tout une telle confiance aux systèmes de fichier, ni d'ailleurs à la manière dont les OS les appellent, ni à la manière dont Java appelle l'OS.
thelvin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 21h45   #14
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
Bon avec l'aide d'un pote et la votre j'ai nettoyé mon code et ça fonctionne.

Le truc qui m'a sauvé je pense, c'est de lire le fichier source et de stocker les lignes dans un tableau. Ensuite je le ferme.

Et c'est seulement après que j'écris le nouveau fichier (à partir du tableau donc) qui va venir écraser le fichier source car je lui donne le même nom.

Voilou.

Merci à tous.
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2012, 22h05   #15
Membre Expert
 
Avatar de wax78
 
Homme Renaud Warnotte
Développeur Java
Inscription : août 2006
Messages : 1 128
Détails du profil
Informations personnelles :
Nom : Homme Renaud Warnotte
Âge : 31
Localisation : Belgique

Informations professionnelles :
Activité : Développeur Java
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : août 2006
Messages : 1 128
Points : 1 807
Points : 1 807
Envoyer un message via MSN à wax78
C'est une solution ... mais qui n'en est pas une.

Tu n'as pas réellement résolu ton problème, juste contourné.

Imagine maintenant que je te donne des fichiers de 10 Gigas a traiter, tu vas mettre ca dans des tableau ? :p (not enough memory)

Le fichier d'origine il n'est pas crée pas un autre process qui ne l'aurait pas bien fermé ? Il vient d'où ce fichier ? Il est la depuis combien de temps etc
wax78 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 08/02/2012, 10h27   #16
Membre à l'essai
 
Avatar de docv266
 
Inscription : août 2007
Messages : 77
Détails du profil
Informations forums :
Inscription : août 2007
Messages : 77
Points : 20
Points : 20
Citation:
Envoyé par wax78 Voir le message
C'est une solution ... mais qui n'en est pas une.

Tu n'as pas réellement résolu ton problème, juste contourné.

Imagine maintenant que je te donne des fichiers de 10 Gigas a traiter, tu vas mettre ca dans des tableau ? :p (not enough memory)

Le fichier d'origine il n'est pas crée pas un autre process qui ne l'aurait pas bien fermé ? Il vient d'où ce fichier ? Il est la depuis combien de temps etc
Oui tu as raison le problème est contourné.
Effectivement mes fichiers font une centaine de ligne grand max donc ça passe en utilisant un tableau.

Les fichiers lus sont mes données d'entrée, ils ne sont pas créés par mon application.

Je ne peux pas dire pourquoi ma première solution posait des problèmes de suppression, c'est d'ailleurs pourquoi j'ai demandé de l'aide sur le forum.
docv266 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2012, 10h42   #17
Rédacteur/Modérateur
 
Avatar de adiGuba
 
Homme
Développeur Java/Web
Inscription : avril 2002
Messages : 12 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Corse (Corse)

Informations professionnelles :
Activité : Développeur Java/Web
Secteur : Transports

Informations forums :
Inscription : avril 2002
Messages : 12 460
Points : 19 447
Points : 19 447
Citation:
Envoyé par docv266 Voir le message
Je ne peux pas dire pourquoi ma première solution posait des problèmes de suppression, c'est d'ailleurs pourquoi j'ai demandé de l'aide sur le forum.
Le problème c'est que tu as donné un code "bien simplifié", donc il est fort possible que l'origine du problème ait été perdu lors de cette simplification. Sans le code exact tu n'auras pas de solution exacte...


Sous Windows, l'appel de delete() échoue s'il reste des flux ouverts sur le fichier.


a++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java Présentation de Java SE 7 (commentaires)
adiGuba est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 01h46.


 
 
 
 
Partenaires

Hébergement Web