Changement d'extension de multiples fichiers [Résolu]

ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 13 avril 2018 à 17:22 - Dernière réponse : vb95 1501 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention
- 14 avril 2018 à 17:35
Bonjour,

Je rencontre récemment un problème dans un code C#. En effet mon but est de détecter automatiquement tout les fichiers présents dans un dossier donné et d'en changer leur extension.
J'ai donc essayé de faire ceci à partir de ce code :
           
string fExt;
string fnExt = ".xbxo";
string fFromName;
string fToName;

string fPath = @"C:\Users\ToxicHayabusa\Desktop\Test";
FileInfo[] files = new DirectoryInfo(fPath).GetFiles();
foreach (var f in files)
{
fFromName = Path.GetFileNameWithoutExtension(f.Name);

fExt = Path.GetExtension(f.Name);

fFromName = string.Format("{0}", f.Name);

fToName = string.Format("{0}{1}", f.Name, fnExt);

File.Move(fFromName, fToName);

}

Ce code est un mélange que j'ai pu faire à partir de deux codes trouvés sur internet...Malheureusement il ne fonctionne pas comme je le voudrais. En effet, là où ça bloque c'est à la dernière ligne, pour le File.Move, car lorsque la commande est donc censé remplacer les anciens fichiers avec les nouveaux portant la nouvelle extension, celui-ci cherche les fichiers dans le dossier local et non dans le dossier précisé au début du code..

Je ne sais pas si le code est maladroit ou mal fait, malgré mes recherches je n'ai pas trop réussit à comprendre les méthodes utilisé pour tout ça et donc il se peut que le code soit même totalement faux, c'est pour cela que je requiert votre aide, pour m'indiqué là où se trouverait le problème et même corriger mon code si possible.

Merci d'avance.
Afficher la suite 

30 réponses

Répondre au sujet
Whismeril 11402 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention - 13 avril 2018 à 17:36
0
Utile
13
Bonjour
trouver des bouts de code sur internet c'est une chose, mais les fusionner sans comprendre c'est pas le mieux.
Pour les comprendre, y'a 2 options (cumulables),

Si tu avais appliqué une seule des ces 2 options, tu n'aurais pas posé cette question, car tu aurais vu que
Path.GetFileNameWithoutExtension(f.Name);
ne retourne que le nom du fichier et pas le chemin complet.

Donc tu aurais peut-être demandé comment changer ton extension et là encore, en lisant la doc en ligne ou même en ayant un peu de curiosité avec la class Path (qu'est ce propose intellisense que je tape Path. ?), tu aurais pu voir la méthode ChangeExtension https://msdn.microsoft.com/en-us/library/system.io.path.changeextension(v=vs.110).aspx

ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 14 avril 2018 à 00:40
Ok, au pire si tu lisais mieux ce que je te répondais :
• je prend les conseilles, j'ai même testé tes codes et je t'ai montré qu'ils
ne fonctionnaient pas (je les ai vraiment testé)
• J'ai déjà dis plus haut que j'avais déjà lu ces docs et que je ne les
avaient pas trouvé utiles.

Tu parles de bénévolat, mais ce que tu te contentes de faire c'est de suivre l'exemple de Microsoft dans leur doc alors que comme tu pourras le voir, dans la doc ils renvoient juste une valeur string en echo, donc forcément qu'ils vont avoir le chemin vers le dossier, en revanche ils ne mettent jamais en pratique la commande pour remplacer l'extension d'un fichier. Et la seule commande que tu m'as donné était une version compacté de la mienne, et malgré ça je l'ai essayée, et ça ne fonctionnait pas non plus.
Whismeril 11402 Messages postés mardi 11 mars 2003Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention - 14 avril 2018 à 13:06
• je prend les conseilles, j'ai même testé tes codes et je t'ai montré qu'ils
ne fonctionnaient pas (je les ai vraiment testé)

ben non, moi je t'ai proposé
File.Move(f.Name, nouveauNom);
et toi tu m'as répondu essayer
File.Move(fFromName + fExt, fToName);
aucun rapport

si on imagine que ton fichier est C:\Toto\tutu.txt
Ce que je te proposais revenait à
File.Move("C:\Toto\tutu.txt", "C:\Toto\tutu.csv");
chemin complet d'un fichier qui existe vers un nouveau nom.
Et toi
File.Move("tutu" + "txt", "C:\Toto\tutu.csv");
ou p'tet
File.Move("tutu" + ".txt", "C:\Toto\tutu.csv");
(j'ai toujours pas testé, j'ai pas plus d'EDI qu'hier sous la main) fichier qui n'existe pas.
Je te l'ai dit dès le premier message.

Y'a la raison évidente que je t'ai donnée, à savoir Path.GetFileNameWithoutExtension. Mais peut être aussi que f.Name est un chemin relatif (toujours pas d'EDI pour vérifier).
Je t'ai aussi conseillé d'exécuter en pas à pas et de regarder le contenu des variables à chaque étape.
Si tu avais fait ça (tout court? sérieusement?), tu aurais du voir que d'une part, tu n'avais pas le chemin complet et que d'autre part il manquait un "\" quelque part.


D'autre part, c'est pas parce que tu n'as pas compris la doc Microsoft qu'elle n'est pas utile.
C'est pas toujours super clair, je te l'accorde (traduction parfois malheureuse je suppose), mais y'a généralement tout ce qu'il faut dedans, et là c'est le cas.

Dans l'exemple de File.Move, il y a des chemins complets
https://msdn.microsoft.com/fr-fr/library/system.io.file.move(v=vs.110).aspx

Dans celle de Path.GetFileNameWithoutExtension y'a bien écrit qu'on perd le chemin du dossier.

Pour Path.ChangeExtension
dans la doc ils renvoient juste une valeur string en echo
oui!!!! C'est File.Move qui renomme un fichier, il faut donc lui donner un nom à appliquer
File.Move(f.Name, Path.ChangeExtension(f.Name, '.csv"));



Donc oui, j'ai cherché à te faire réfléchir par toi même, parce que d'une part c'est la règle de ce forum et d'autre part sans EDI pas de code certifié efficace.

Par contre, je peux te proposer d'utiliser Directory.GetFiles() https://msdn.microsoft.com/fr-fr/library/system.io.directory.getfiles(v=vs.110).aspx, plutôt que new DirectoryInfo(fPath).GetFiles() parce que je suis sûr que ça retourne les chemins complets et qu'en plus y'a une option pour obtenir le contenu de tous les sous répertoires.
Ça tient en 2 lignes et ça évite la récursivité (toujours pas testé)
foreach(string f in Directory.GetFiles(@"C:\Users\ToxicHayabusa\Desktop\Test","*.txt",SearchOption.AllDirectories))
           File.Move(f, Path.ChangeExtension(f, '.csv")); 
vb95 1501 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention - 14 avril 2018 à 15:37
bonjour Whismeril
Je viens d'essayer avec ton code juste au-dessus !
cela fonctionne très bien
Moi je l'ai fait avec "*.*" en second paramètre ce qui me change toutes les extensions trouvées dans le répertoire et tous les sous-répertoires
foreach(string f in Directory.GetFiles(@"C:\Users\ToxicHayabusa\Desktop\Test","*.*",SearchOption.AllDirectories))
           File.Move(f, Path.ChangeExtension(f, '.csv")); 


comme quoi que chercher dans MSDN est une mine d'informations
A ++
ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 14 avril 2018 à 16:39
Je t'ai dis que j'avais essayé avec ton code, je n'ai pas forcément partager le code. J'essayais juste de multiples codes, et je partageais ceux que je faisais moi même pour comprendre ce qui n'allait pas, mais je testais aussi ceux proposés à côté. Merci de bien lire mes réponses.

Je n'ai pas dis que je ne comprenais pas les docs, juste qu'ils ne faisaient pas assez de mise en pratique dans leurs exemples, ce qui serait tout de même plus intéressant. J'ai quant à moi trouvé bien plus d'informations utiles sur des sites comme StackOverflow ou CodeProject.
ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 14 avril 2018 à 17:00
En revanche je te remercie pour le temps consacré, je sais que ce ne doit pas être facile d'aider sans donner de code, surtout avec moi, car j'ai souvent besoin d'exemples concrets pour mieux comprendre des codes.. (je préfère analyser un code complet pour savoir l'utiliser que de voir des petits exemples pas très concrets..)
Commenter la réponse de Whismeril
ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 13 avril 2018 à 22:22
0
Utile
1

Voici l'image.

En revanche le code donné résume simplement mon code actuel, pour preuve je l'ai testé, et il fait exactement la même erreur que mon code.
vb95 1501 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention - 13 avril 2018 à 23:03
Bonsoir !
La solution est ici

string newextension = ".xbxo";
string filename;
string fpath = @"D:\Test\";
FileInfo[] files = new DirectoryInfo(fpath).GetFiles();
foreach (FileInfo f in files)
{
filename = Path.ChangeExtension(f.Name, newextension);
File.Move(fpath + f.Name, fpath + filename);
}


Lors du File.Move il faut préciser le répertoire des fichiers sinon C# prend le dossier de l'application par défaut : c'est cela que l'on appelle un chemin relatif comme dit Whismeril !
Commenter la réponse de ToxicHayabusa
ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 14 avril 2018 à 00:47
0
Utile
13

J'apprécie l'aide proposée, en revanche, comme je l'ai dis plus haut cette méthode ne fonctionne pas. Je ne suis pas débile non plus, j'ai très bien compris la méthode et comment elle est censée fonctionner, et j'ai aussi essayé de mon côté plusieurs possibilités de code, toutes menant à la même erreur.

(Au passage, avec votre méthode VB95, le programme rajoute même le nom du dossier en plus du chemin au nom du fichier qu'il cherche..)
vb95 1501 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention - 14 avril 2018 à 04:04
Cadeau !
Et j'ai testé

private void Button1_Click(object sender, EventArgs e) 
        {
            Changeextension(@"D:\Test");  // répertoire source
        }

        private void Changeextension(string fpath) 
        {
            string newextension = ".xbxo";
            string filename;
            // on recherche les fichiers et les sous-répertoires du répertoire courant
            String[] files = Directory.GetFileSystemEntries(fpath);
            foreach (String file in files)
            {
                // Vérification si c'est un fichier ou un répertoire 
                FileInfo f = new FileInfo(file);
                fpath = f.Directory + "\\";
                FileAttributes Fa = File.GetAttributes(f.FullName);
                if ((Fa & FileAttributes.Directory) == FileAttributes.Directory)
                   // répertoire 
                   Changeextension(f.FullName);
                else
                   // fichier 
                {
                filename = Path.ChangeExtension(f.Name, newextension);
                File.Move(fpath + f.Name, fpath + filename);
                }
            }
        }

Comme tu le vois la fonction Changeextention s'appelle elle-même dès que la fonction trouve un répertoire .
C'est ça la récursivité

Attention le répertoire d'origine n'a pas d'antislash ici
Changeextension(@"D:\Test");  // répertoire source

L'antislash est rajouté dans la fonction elle-même
ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 14 avril 2018 à 04:27
Franchement merci ! J'avais compris pour la récursivité en revanche, comme vous pouviez le voir dans mon essai de code précédent.. Mais il me manquait pas mal de notions (comme FileAttributes et Directory.GetFileSystemEntries (qui d'ailleurs je n'aurais jamais soupçonné servir à ce à quoi il sert vu le nom..)) Sur ce je vais bien étudié ce code dans le but de bien le comprendre, et je vais enfin pouvoir continuer mon long travail qui m'attend..

Merci encore.

ps: Même avec un antislash dans le répertoire d'origine, cela fonctionne
ToxicHayabusa 868 Messages postés dimanche 7 décembre 2014Date d'inscription 18 avril 2018 Dernière intervention - 14 avril 2018 à 16:42
J'ai remarqué que dans le code il manquait une chose en revanche, si le fichier est utilisé par un processus en cours, le logiciel ne réussira pas à le modifier et risque de planter, j'ai donc rajouté un "try {} catch{}" au niveau de
                {
                filename = Path.ChangeExtension(f.Name, newextension);
                File.Move(fpath + f.Name, fpath + filename);
                }

ce qui donne (pour ceux venant chercher de l'aide sur ce code)
         {
                    try
                    {
                        filename = Path.ChangeExtension(f.Name, newextension);
                        File.Move(fpath + f.Name, fpath + filename);
                    }
                    catch { }
                }

De cette manière il ne prendra pas en compte les erreurs et continuera le code.
vb95 1501 Messages postés samedi 11 janvier 2014Date d'inscriptionContributeurStatut 19 avril 2018 Dernière intervention - 14 avril 2018 à 17:35
Bonjour !
Tout à fait judicieux !
Si tu en avertissait l'utilisateur

         {
                    try
                    {
                        filename = Path.ChangeExtension(f.Name, newextension);
                        File.Move(fpath + f.Name, fpath + filename);
                    }
                    catch ex as Exception
                   {
                      MessageBox.Show(ex.message + Environment.newline +"Changement extension non fait sur" + fpath + f.Name + " (fichier utilisé)")

                   }    
     }


As-tu regardé les messages 25 et 26 qui proposent une alternative sans récursivité visible ?
Mais ainsi pas de Try Catch possible
Commenter la réponse de ToxicHayabusa

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.