Obtention de noms de fichiers sans extensions


279

Lors de l'obtention des noms de fichiers dans un certain dossier:

DirectoryInfo di = new DirectoryInfo(currentDirName);
FileInfo[] smFiles = di.GetFiles("*.txt");
foreach (FileInfo fi in smFiles)
{
    builder.Append(fi.Name);
    builder.Append(", ");
    ...
}

fi.Nameme donne un nom de fichier avec son extension: file1.txt, file2.txt, file3.txt.

Comment puis-je obtenir les noms de fichiers sans les extensions? ( file1, file2, file3)

Réponses:


479

Vous pouvez utiliser Path.GetFileNameWithoutExtension:

foreach (FileInfo fi in smFiles)
{
    builder.Append(Path.GetFileNameWithoutExtension(fi.Name));
    builder.Append(", ");
}

Bien que je sois surpris, il n'y a aucun moyen d'obtenir cela directement à partir du FileInfo(ou du moins je ne le vois pas).


7
Et pour obtenir l'extension (à ajouter plus tard par exemple), utilisez: Path.GetExtension (fileName);
Justin

2
@Juzzz C'est pratique si vous travaillez avec une chaîne nue, mais si vous avez déjà un objet FileInfo, il n'est pas nécessaire de s'embêter avec Path. FileInfo fournit déjà la propriété "Extension" à cet effet.
jmbpiano

J'ai eu l'erreur "'builder' n'existe pas dans le contexte actuel". J'ai ajouté 'system.Text' mais j'ai toujours la même erreur. Quelle est la raison?
ffttyy

@ffttyy buildersera une instance de StringBuilderdans le code OP. C'est juste un exemple d'utilisation de GetFileNameWithoutExtension - vous ferez probablement mieux d'écrire votre propre code qui l'appelle.
Rup

9
Une erreur à noter ici est que si votre fichier contient une double extension, GetFileNameWithoutExtensionne supprime que l' extension de fin . Par exemple, le nom de fichier example.es6.jsdeviendraexample.es6
David Roberts

48

Notez que Path.GetFileNameWithoutExtension n'est pas le meilleur moyen car il vérifie les caractères de chemin non valides et essaie d'extraire DirectorySeparatorChar, AltDirectorySeparatorChar ou VolumeSeparatorChar dans une boucle qui ne semble pas nécessaire pour les noms de fichiers (pas les chemins complets)!
S.Serpooshan

22

Cette solution empêche également l'ajout d'une virgule de fin.

var filenames = String.Join(
                    ", ",
                    Directory.GetFiles(@"c:\", "*.txt")
                       .Select(filename => 
                           Path.GetFileNameWithoutExtension(filename)));

Je n'aime pas DirectoryInfo, FileInfo pour ce scénario.

DirectoryInfo et FileInfo collectent plus de données sur le dossier et les fichiers que nécessaire, ce qui leur prend plus de temps et de mémoire que nécessaire.


2
+1. Je préfère aussi Directory.GetFilessur DirectoryInfo.GetFilesanyday, si tout ce que je veux est des noms de fichiers.
Yogesh

J'aime ça parce que String.Join, LINQ, pas de StringBuilder.
Csaba Toth du

Si vous regardez le code source. Le constructeur de FileInfo est très léger. Et toutes les informations que vous voyez se font via les propriétés. Ils ne sont rassemblés que lorsque vous les appelez
fjch1997

@ fjch1997 - Le constructeur appelle Path.GetFileName et vérifie les autorisations. Cela semble donc un peu redondant.
Erno

@ErnodeWeerd FileIOPermission ne vérifie pas l'autorisation par rapport à l'ACL. à la place, c'est une sorte de mécanisme dans .NET pour vérifier l'autorisation pour le code partiellement approuvé. Donc, il ne devrait pas faire d'appel IO réel. Quel impact cela a-t-il sur les performances? je ne peux pas dire sans tester. Mais je suppose que ce n'est pas si génial
fjch1997

10

Utilisez Path.GetFileNameWithoutExtension. Le chemin se trouve dans l'espace de noms System.IO.



6

En tant que réponse supplémentaire (ou pour compléter les réponses existantes), vous pouvez écrire une méthode d'extension pour accomplir cela pour vous dans la classe DirectoryInfo. Voici un exemple que j'ai écrit assez rapidement qui pourrait être embelli pour fournir des noms de répertoire ou d'autres critères de modification, etc.:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace DocumentDistributor.Library
{
    public static class myExtensions
    {
        public static string[] GetFileNamesWithoutFileExtensions(this DirectoryInfo di)
        {
            FileInfo[] fi = di.GetFiles();
            List<string> returnValue = new List<string>();

            for (int i = 0; i < fi.Length; i++)
            {
                returnValue.Add(Path.GetFileNameWithoutExtension(fi[i].FullName)); 
            }

            return returnValue.ToArray<string>();
         }
    }
}

Edit: Je pense également que cette méthode pourrait probablement être simplifiée ou géniale si elle utilisait LINQ pour réaliser la construction du tableau, mais je n'ai pas l'expérience de LINQ pour le faire assez rapidement pour un échantillon de ce type.

Edit 2 (près de 4 ans plus tard): Voici la méthode LINQ-ified que j'utiliserais:

public static class myExtensions
{
    public static IEnumerable<string> GetFileNamesWithoutExtensions(this DirectoryInfo di)
    {
        return di.GetFiles()
            .Select(x => Path.GetFileNameWithoutExtension(x.FullName));
    }
}

5

FileInfo connaît sa propre extension, vous pouvez donc la supprimer

fileInfo.Name.Replace(fileInfo.Extension, "");
fileInfo.FullName.Replace(fileInfo.Extension, "");

ou si vous êtes paranoïaque qu'il pourrait apparaître au milieu, ou que vous souhaitez microoptimiser:

file.Name.Substring(0, file.Name.Length - file.Extension.Length)

4

si le nom du fichier contient un répertoire et que vous ne devez pas perdre de répertoire:

fileName.Remove(fileName.LastIndexOf("."))

2

essaye ça,

string FileNameAndExtension =  "bılah bılah.pdf";
string FileName = FileNameAndExtension.Split('.')[0];

1

Juste pour info:

DirectoryInfo di = new DirectoryInfo(currentDirName);
FileInfo[] smFiles = di.GetFiles("*.txt");
string fileNames = String.Join(", ", smFiles.Select<FileInfo, string>(fi => Path.GetFileNameWithoutExtension(fi.FullName)));

De cette façon, vous n'utilisez pas StringBuildermais String.Join(). Veuillez également noter qu'il a Path.GetFileNameWithoutExtension()besoin d'un chemin complet ( fi.FullName), pas fi.Namecomme je l'ai vu dans l'une des autres réponses.


-5
using System;

using System.IO;

public class GetwithoutExtension
{

    public static void Main()
    {
        //D:Dir dhould exists in ur system
        DirectoryInfo dir1 = new DirectoryInfo(@"D:Dir");
        FileInfo [] files = dir1.GetFiles("*xls", SearchOption.AllDirectories);
        foreach (FileInfo f in files)
        {
            string filename = f.Name.ToString();
            filename= filename.Replace(".xls", "");
            Console.WriteLine(filename);
        }
        Console.ReadKey();

    }

}

5
Vous ne semblez pas être conscient qu'il existe déjà une classe Framework qui fait cela pour vous.
Andrew Barber

3
De plus, si quelqu'un a nommé ses fichiers "Current.XLSFiles.xls", cela va provoquer de VRAIS problèmes.
Tom Padilla

@TomPadilla pourquoi cela causerait-il des problèmes?
Luke101

Parce que cette méthode présenterait "Current.files" comme nom de fichier. Parce que chaque instance de ".xls" serait remplacée par "", y compris celles au milieu du nom.
Tom Padilla
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.