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 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.
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),
exécuter en pas à pas et regarder le résultat de chaque étapes.
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
Oui ok, sauf que tout ça je l'ai déjà lu au par avant, et que je sais que
Path.GetFileNameWithoutExtension(f.Name);
ne retourne que le nom du fichier. Sauf que j'ai déjà essayé avec une précédente méthode (d'ailleurs la doc de microsoft ne sert pas à grand chose) où j'implémentais le chemin du fichier dans le nom, et le logiciel se contentait de chercher le fichier avec le chemin dans le nom..
. Ça ne peut pas marcher, et contrairement à ce que tu dis, en lisant correctement la doc et en exécutant pas à pas tu aurais pu le voir par toi même.
De tête (et par conséquent sans test)
string ext = Path.GetExtension(f.Name);
string nouveauNom = f.Name.Replace(ext, ".csv");//là on converse le chemin complet
Path.Move(f.Name, nouveauNom);//là aussi
Mais vu, que Path propose une méthode qui fait le job, pourquoi ne pas tout simplement pas s'en servir?
Bref comme je le disais, tu viens exactement de me montrer une méthode que j'avais utilisée et qui ne fonctionnait pas car comme dit plus haut, le logiciel cherche donc le fichier avec le chemin dans son nom (au passage Path.Move n'existe pas, et Path.ChangeExtension (que j'ai essayé au cas où) ne fait juste rien du tout, ni erreur ni résultat)
Que veux-tu dire par "Path propose une méthode qui fait le job" ? Si tu parles de "Path.ChangeExtension", comme dis plus haut, il ne fait rien (et je ne sais pas pourquoi d'ailleurs)
string fPath = @"C:\Users\ToxicHayabusa\Desktop\Test"; FileInfo[] files = new DirectoryInfo(fPath).GetFiles(); foreach (var f in files) { //get the filename without the extension fFromName = Path.GetFileNameWithoutExtension(f.Name); //get the file extension fExt = Path.GetExtension(f.Name);
Oui merci, je sais comment utiliser correctement les balises de code, je trouve ça juste inutile...Après si tu le souhaites je pourrais à l'avenir y régler en C#.
Oui merci, je sais comment utiliser correctement les balises de code, je trouve ça juste inutile
et moi je trouve juste pénible de lire un pavé tout gris et moche.
En tant que bénévole, je ne vais pas me compliquer la vie pour quelqu'un qui ne le mérite pas:
tu ne prends pas les conseils que l'on te donne.
tu n'essayes pas les codes que l'on te propose.
tu ne juges pas utiles de lire la doc. (Path.ChangeExtension fonctionne très bien, il faut juste l'utiliser comme il est prévu).
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.
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.
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"));
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 ++
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.
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..)
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 !
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..)
Bonsoir !
J'ai moi-même testé sur 2 fichiers dans un répertoire et elle fonctionne très bien
As-tu bien mis un antislash à la fin de la String fpath ?
Car entre Test et 456.pxd il n'y est pas ce qui fait qu'il ne peut pas trouver les fichiers !
et aussi remplace var par FileInfo dans le foreach car f est une variable de type FileInfo
De plus tu écris : (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..)
le nom du dossier c'est le chemin et pour chercher un fichier il faut
1) son chemin ( le répertoire où il se trouve )
2) son nom avec l'extension
filename et f.name ne sont que les noms des fichiers . il faut rajouter fpath qui est le chemin de ces fichiers ( le répertoire qui les contient)
Ok, le problème venait simplement de l'anti slash, j'avoue ne pas avoir pensé à ça...Merci de l'aide !
Comme quoi, rien ne sert de s'énerver à m'expliquer 30 fois la même chose, le mieux serait encore de bien regarder mon code :) (surtout qu'il n'est pas très long..)
Oui mais bon, pour ce genres de choses, je ne vois pas en quoi je n'aurais rien appris...Vu que c'était juste un caractère oublié.
Sinon j'ai essayé un code comme ceci :
string fnExt = ".pwned";
string filename;
string npath;
string fPath = @"C:\Users\ToxicHayabusa\Desktop\Test\";
FileInfo[] files = new DirectoryInfo(fPath).GetFiles();
string[] folders = Directory.GetDirectories(fPath);
foreach (var f in files)
{
filename = Path.ChangeExtension(f.Name, fnExt);
File.Move(fPath + f.Name, fPath + filename);
}
foreach (var d in folders)
{
npath = Path.GetDirectoryName(d);
FileInfo[] nfiles = new DirectoryInfo(npath).GetFiles();
foreach (FileInfo f in nfiles)
{
filename = Path.ChangeExtension(f.Name, fnExt);
File.Move(npath + f.Name, npath + filename);
}
}
Mais ça n'a pas l'air de fonctionné du tout...Est-ce que je suis dans la mauvaise direction ou bien y'a des choses qui pourraient fonctionner dedans ? (et donc dans ce cas il faut que je continue à chercher à modifier le code pour qu'il fonctionne..)
(ps : je viens de voir que les balises de code C# semblent un peu buggées..)
EDIT:Je viens de lire la doc Microsoft sur Path.GetDirectoryName, je comprend mieux pourquoi ça ne fonctionne pas, mais y a-t-il un moyen d'obtenir le nom du dossier concerné ? Et non sa racine ?
bonsoir !
1) vire moi cette affreux var ! l'un est un type FileInfo et l'autre un type string !
2) il faut en faire une fonction que tu rappelles à chaque sous-répertoire
Fonction ModifieExtension( dossier)
---------------Pour chaque fichier dans ce répertoire
--------------------Teste si fichier ou répertoire
------------------------------- Si répertoire on rappelle la fonction ModifieExtension avec le nouveau dossier ( c'est la récursivité ) ---> voir note
-------------------------------- Si c'est un fichier on change l'extension
---------------------Fin du test fichier/répertoire
---------------Fin exploration répertoire
Fin de la Fonction
Note : le nouveau dossier est formé du dossier actuel auquel on rajoute le répertoire trouvé
Attention tous les sous-dossiers seront explorés
Bon j'ai finis par trouvé par moi même, j'avais seulement deux petites choses à changer dans le code ! (et pour vous faire plaisir j'ai retiré ce "var" ;) )
Voici le code final !
string fnExt = ".pwned";
string filename;
string npath;
string fPath = @"C:\\Users\\ToxicHayabusa\\Desktop\\Test\\";
FileInfo[] files = new DirectoryInfo(fPath).GetFiles();
string[] folders = Directory.GetDirectories(fPath);
foreach (FileInfo f in files)
{
filename = Path.ChangeExtension(f.Name, fnExt);
File.Move(fPath + f.Name, fPath + filename);
}
foreach (string d in folders)
{
npath = Path.GetFullPath(d);
FileInfo[] nfiles = new DirectoryInfo(npath).GetFiles();
int pathlg = npath.Length;
npath = npath.Insert(pathlg , "\\");
foreach (FileInfo f in nfiles)
{
filename = Path.ChangeExtension(f.Name, fnExt);
File.Move(npath + f.Name, npath + filename);
}
}
ps: afin de rendre le code plus lisible sur le site, j'ai temporairement modifié le chemin "@"C:\Users\ToxicHayabusa\Desktop\Test\" en "@"C:\\Users\\ToxicHayabusa\\Desktop\\Test\\" "
EDIT: Finalement je me suis rendu compte que mon code se limitait aux sous fichiers au premier degré, et ne prend donc pas en compte les sous-sous fichiers ect..
Du coup je me retrouve de nouveau bloqué, car à moins de faire une boucle de la même méthode des dizaine de fois pour être sûr que ça prendra en compte tout les sous dossiers possibles, il faut que je trouve une méthode plus viable..
En revanche pour la méthode que vous me proposez c'est malheureusement d'un niveau trop élevé pour moi, je ne sais même pas comment tester si cela peut être un fichier ou un répertoire (d'ailleurs, ne fait-il pas déjà la différence ? Puisqu'il me semble que FileInfo ne prend en compte que les fichiers et non dossiers..)
En suivant de mon mieux votre méthode, j'ai donc élaboré ce code, qui ne fonctionne pas pour autant, et je ne comprend pas pourquoi..
string fnExt = ".pwned";
string filename;
string npath;
string fPath = @"C:\\Users\\ToxicHayabusa\\Desktop\\Test\\";
FileInfo[] files = new DirectoryInfo(fPath).GetFiles();
string[] folders = Directory.GetDirectories(fPath);
foreach (FileInfo f in files)
{
filename = Path.ChangeExtension(f.Name, fnExt);
File.Move(fPath + f.Name, fPath + filename);
}
foreach (string d in folders)
{
void ChangeExt()
{
npath = Path.GetFullPath(d);
FileInfo[] nfiles = new DirectoryInfo(npath).GetFiles();
string[] nfolders = Directory.GetDirectories(npath);
int pathlg = npath.Length;
npath = npath.Insert(pathlg, "\\");
foreach (FileInfo f in nfiles)
{
filename = Path.ChangeExtension(f.Name, fnExt);
File.Move(npath + f.Name, npath + filename);
}
foreach (string x in nfolders)
{
ChangeExt();
}
}
}
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
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
13 avril 2018 à 18:33
Modifié le 13 avril 2018 à 18:35
Donc je vois pas où est le problème ? Pour moi, le code est censé toujours chercher les fichiers dans ce chemin, puisqu'il les a bien trouvé au début.
13 avril 2018 à 18:54
Ce que tu codes c'est . Ça ne peut pas marcher, et contrairement à ce que tu dis, en lisant correctement la doc et en exécutant pas à pas tu aurais pu le voir par toi même.
De tête (et par conséquent sans test)
Mais vu, que Path propose une méthode qui fait le job, pourquoi ne pas tout simplement pas s'en servir?
13 avril 2018 à 19:04
Que veux-tu dire par "Path propose une méthode qui fait le job" ? Si tu parles de "Path.ChangeExtension", comme dis plus haut, il ne fait rien (et je ne sais pas pourquoi d'ailleurs)
13 avril 2018 à 19:26
https://image.noelshack.com/fichiers/2018/15/5/1523640390-894ef.png