Renommer un fichier en java sans un "?"

Résolu
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention   -  
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention   -

bonjour,

J'ai un dossier dans lequel sont enregistrés des fichiers ".txt". Certains de ces fichiers sont nommés avec des "?". Par exemple : ddffgfg? ooodkf ?njnj.txt

Je souhaite les supprimer les "?". 

Voici mon code ci-dessous.

J'ai 2 problemes : 

- tous les fichiers n'ont pas leur "?" supprimé

- ma boucle semble ne pas fonctionner

Auriez-vous une idée ? Merci d'avance. 

public class RenameFilesJava {

public static void main(String[] args)

{

File dossier = new File("/Users/bou/Stockage");

File[] liste = dossier.listFiles();

for (int i = 0; i < liste.length; i++) {

if (liste[i].isFile()) { // si c'est un fichier

//récupérer le fichier en cours

File f = new File("/Users/bou/Stockage/"+liste[i].getName());

String nomAncien = liste[i].getName();

System.out.println("nomAncien : " + nomAncien);

//String carAsup = "?";

String nomNouveau = "";

//nomNouveau = nomAncien.replaceAll("\\p{Punct}", "");

//nomNouveau =  nomAncien.replaceAll("[!\"#$%&'()*+,-./:;<=>?@\\[\\]^_`{|}~]", "");

nomNouveau =  nomAncien.replaceAll("[?]", "");

f.renameTo(new File("/Users/bou/Stockage/"+ nomNouveau));

//System.out.println("carAsup : " + carAsup);

System.out.println("nomNouveau : " + nomNouveau);

}

}

}

}

A voir également:

6 réponses

KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 

Bonjour,

replaceAll prends en paramètre une regex, or le ? est un caractère spécial pour les expressions régulières.

Soit tu utilises plutôt la méthode replace qui prends en paramètre un String, dans ce cas tu peux mettre "?" en paramètre. Soit tu continues avec replaceAll mais il faut alors échapper le ? avec un \ dans la regex (qui lui même doit être échappé par un autre \ dans le String)

nomNouveau = nomAncien.replace("?", "");
nomNouveau = nomAncien.replaceAll("\\?", "");

0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Bonjour,

Je suis sur MAc.

nomNouveau = nomAncien.replace("?", "");
nomNouveau = nomAncien.replaceAll("\\?", "");

cela ne fonctionne tjrs pas et je ne comprends pas

0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020 > azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Ces deux lignes fonctionnent bien. Mais une seule suffira, elles font la même chose.

Exemple :

public class Test {
    public static void main(String args[]) {
        String nomAncien = "abc?def?ghi";
        System.out.println(nomAncien.replace("?", "")); // abcdefghi
        System.out.println(nomAncien.replaceAll("\\?", "")); // abcdefghi
    }
}
1
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020 > azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Code complet pour faire le renommage de tous les fichiers dans ton répertoire :

import java.io.File;

public class RenameFilesJava {
    public static void main(String[] args) {
        for (File file : new File("/Users/bou/Stockage").listFiles()) {
            if (file.getName().contains("?")) {
                File renameFile = new File(file.getParentFile(), file.getName().replace("?", ""));
                boolean result = file.renameTo(renameFile);
                System.out.println(file + " => " + renameFile + " => " + (result ? "OK" : "KO"));
            }
        }
    }
}
0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention   > KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention  
 

Nickel ! Le code fonctionne parfaitement. Merci KX. 

0
brucine Messages postés 21598 Date d'inscription   Statut Membre Dernière intervention   3 394
 

Bonjour,

Je ne comprends rien à Java, je commente la question par une autre question: le point d'interrogation est un caractère interdit dans le nom des fichiers Windows, ce qui expliquerait le comportement sauf s'il s'agit de Linux/Unix?

Dans ce dernier cas de figure, il existe de nombreuses solutions simples par exemple via bash.

0
brucine Messages postés 21598 Date d'inscription   Statut Membre Dernière intervention   3 394
 
0
hypothetix Messages postés 224 Date d'inscription   Statut Membre Dernière intervention   66
 

Bonjour,

Il ne faut pas échapper le \ donc essaie ceci :

nomNouveau = nomAncien.replaceAll("\?", "");
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 

Si il faut échapper le ? par un \ dans la regex, et en plus échapper le \ dans une String.

On se retrouve avec deux \ dans le code c'est normal.

0
hypothetix Messages postés 224 Date d'inscription   Statut Membre Dernière intervention   66
 

Bonjour KX,

Je dois avouer ne pas comprendre "et en plus échapper le \ dans une String" et ne pas connaitre java, mais en javascript  j'obtiens cela :

<script>
	nomAncien="fff?gg??g";
	nomNouveau = nomAncien.replaceAll("\\?", "");
	console.log(nomAncien,nomNouveau); //fff?gg??g fff?gg??g
	
	nomNouveau = nomAncien.replaceAll("\?", "");
	console.log(nomAncien,nomNouveau); //fff?gg??g fffggg
</script>
0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020 > hypothetix Messages postés 224 Date d'inscription   Statut Membre Dernière intervention  
 

JavaScript ce n'est pas Java, ce sont deux langages différents avec des syntaxes différentes et même si certaines méthodes ont le même nom elles ne font pas forcément exactement la même chose.

En Java : si je veux afficher Bonjour je dois écrire :

System.out.println("Bonjour");

Si je veux par exemple faire une tabulation, ou un saut de ligne, je peux utiliser les caractères \t ou \n qui sont écrits avec une combinaison d'un \ et d'une lettre

System.out.println("Bonjour\nLa ligne");

Il peut y avoir des combinaisons plus compliqués, par exemple pour les caractères Unicode avec \u suivi du code hexadécimal du caractère.

Bref, le \ est un caractère d'échappement utilisé dans des combinaisons de caractère dans les String en Java et si on veut juste afficher le \ il faut utiliser la combinaison \\

System.out.println("Bonjour \\ le slash");

Ce qui affichera Bonjour \ le slash

Donc lorsque l'on écrit une regex avec un \ comme dans \? il faut l'échapper et écrire "\\?"

Remarque : dans les regex les \ aussi peuvent être échappés, donc si dans la regex on veut juste le caractère \ il faut l'échapper \\ ce qui dans un String donne "\\\\" avec 4 \

0
hypothetix Messages postés 224 Date d'inscription   Statut Membre Dernière intervention   66
 

OK, merci pour tes explications.

0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Je reviens vers vous car j'ai un autre souci. Je pense que cela est du au "?" qui doit avoir une action.

Dans mon dossier, je vous ai dit que j'ai des fichiers nommé par des "?"

exemple : bou? etrange? 2323232.txt

Le code ne fonctionnait plus car "contains" ne retrouvait pas de ? Etrange, puisque je les vois dans mon dossier ces fameux "?".

J'ai donc récupéré le nom grâce à System.out.println(file.getName()) pour essayer de comprendre  et voici ce que je trouve

bou

etrange

2323232.txt

Comme ci le "?" provoque un retour à la ligne. 

Et donc finalement, mes fichiers ne peuvent etre renommés sans "?"

Pour quelle raison ? Et quelle est la solution ? 

0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 

Bonjour,

De toute évidence ton "?" n'est pas un point d'interrogation, c'est sûrement un affichage par défaut d'un caractère non affichable.

Pour déboguer, tu pourrais afficher le nom de chacun des caractères de tes fichiers.

for (File file : new File("/Users/bou/Stockage").listFiles()) {
    System.out.println(file.getAbsolutePath());
    file.getName().chars().forEach(c ->
        System.out.printf("\t%c\t%d\t%x\t%s%n", c, c, c, Character.getName(c))
    );
}

Exemple (sous Windows), avec le caractère, le code décimal, le code hexadécimal et le nom Unicode.

C:\Program Files (x86)
	P	80	50	LATIN CAPITAL LETTER P
	r	114	72	LATIN SMALL LETTER R
	o	111	6f	LATIN SMALL LETTER O
	g	103	67	LATIN SMALL LETTER G
	r	114	72	LATIN SMALL LETTER R
	a	97	61	LATIN SMALL LETTER A
	m	109	6d	LATIN SMALL LETTER M
	 	32	20	SPACE
	F	70	46	LATIN CAPITAL LETTER F
	i	105	69	LATIN SMALL LETTER I
	l	108	6c	LATIN SMALL LETTER L
	e	101	65	LATIN SMALL LETTER E
	s	115	73	LATIN SMALL LETTER S
	 	32	20	SPACE
	(	40	28	LEFT PARENTHESIS
	x	120	78	LATIN SMALL LETTER X
	8	56	38	DIGIT EIGHT
	6	54	36	DIGIT SIX
	)	41	29	RIGHT PARENTHESIS

Avec ça on devrait identifier le caractère problématique. Imaginons que ce soit par exemple � dont le code hexadécimal est fffd dans ce cas tu peux faire :

replace("\ufffd", "")
0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Génial ! 

Je pense que le "?" correspond à cela 

13 d CARRIAGE RETURN (CR)

0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

J'ai vu le code hexdecimal 0D

https://www.eso.org/~ndelmott/ascii.html

0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020
 

Du coup tu peux faire :

replace("\u000d", "")

Ou plus simplement :

replace("\r", "")
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

tjrs rien. 

ne faudrait-il pas modifier file.getName().contains("?") car finalement ce ? n'est pas une ponctuation ?

0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

En fait voici le code qui fonctionne ci-dessous. J'ai retiré contains car il ne reconnait pas le "?"

public class RenameFilesJava 
{
    public static void main(String[] args) 
{
        for (File file : new File("/Users/bou/Stockage").listFiles()) 
{
            
                File renameFile = new File(file.getParentFile(), file.getName().replace("\r", ""));
                boolean result = file.renameTo(renameFile);
                System.out.println(file + " => " + renameFile + " => " + (result ? "OK" : "KO"));
            
        }
    }
}
0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

D'ailleurs, comment contains pourrait reconnaitre ce carriage return ?

0
KX Messages postés 16761 Date d'inscription   Statut Modérateur Dernière intervention   3 020 > azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Il faut juste remplacer ? par \r partout, donc :

if (file.getName().contains("?")) {
    ... file.getName().replace("?", "")
}
if (file.getName().contains("\r")) {
    ... file.getName().replace("\r", "")
}
0
azerty_qwerty Messages postés 61 Date d'inscription   Statut Membre Dernière intervention  
 

Super ! merci pour les conseils et votre aide. 

0