Ottenere nomi di file senza estensioni


279

Quando si ottengono nomi di file in una determinata cartella:

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

fi.Namemi dà un nome di file con la sua estensione: file1.txt, file2.txt, file3.txt.

Come posso ottenere i nomi dei file senza le estensioni? ( file1, file2, file3)

Risposte:


479

Puoi usare Path.GetFileNameWithoutExtension:

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

Anche se sono sorpreso, non c'è modo di ottenerlo direttamente dal FileInfo(o almeno non riesco a vederlo).


7
E per ottenere l'estensione (da aggiungere in seguito, ad esempio) utilizzare: Path.GetExtension (fileName);
Giustino,

2
@Juzzz È utile se lavori con una stringa nuda, ma se hai già un oggetto FileInfo, non è necessario preoccuparsi di Path. FileInfo fornisce già la proprietà "Extension" allo scopo.
jmbpiano,

Ho ricevuto l'errore "'builder' non esiste nel contesto attuale". Ho aggiunto "system.Text" ma ho ancora riscontrato lo stesso errore. Qual è la ragione?
ffttyy,

@ffttyy buildersarà un'istanza di StringBuildernel codice OP. È solo un esempio di utilizzo di GetFileNameWithoutExtension: probabilmente farai meglio a scrivere il tuo codice che lo chiama.
Rup,

9
Un punto da notare qui è che se il tuo file contiene una doppia estensione, GetFileNameWithoutExtensionrimuove solo l' estensione finale . Ad esempio, il nome del file example.es6.jsdiventeràexample.es6
David Roberts

48

Nota che Path.GetFileNameWithoutExtension non è il modo migliore in quanto verifica la presenza di caratteri di percorso non validi e cerca di estrarre DirectorySeparatorChar, AltDirectorySeparatorChar o VolumeSeparatorChar in un ciclo che non sembra necessario per i nomi dei file (non del percorso completo)!
S. Serpooshan,

22

Questa soluzione impedisce anche l'aggiunta di una virgola finale.

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

Non mi piace DirectoryInfo, FileInfo per questo scenario.

DirectoryInfo e FileInfo raccolgono più dati sulla cartella e sui file di quanto è necessario, quindi richiedono più tempo e memoria del necessario.


2
+1. Preferisco anche Directory.GetFilesogni giorno DirectoryInfo.GetFiles, se tutto ciò che voglio sono i nomi dei file.
Yogesh,

Mi piace perché String.Join, LINQ, no StringBuilder.
Csaba Toth,

Se dai un'occhiata al codice sorgente. Il costruttore di FileInfo è molto leggero. E tutte le informazioni che vedi sono fatte attraverso le proprietà. Sono raccolti solo quando li chiami
fjch1997,

@ fjch1997 - Il costruttore chiama Path.GetFileName e verifica le autorizzazioni. Quindi sembra un po 'ridondante.
Erno,

@ErnodeWeerd FileIOPermission non controlla l'autorizzazione per l'ACL. invece è una sorta di meccanismo in .NET per verificare l'autorizzazione per il codice parzialmente attendibile. Quindi, non dovrebbe effettuare alcuna chiamata IO effettiva. Quanto influisce sulle prestazioni? non posso dire senza test. Ma presumo che non sia eccezionale
fjch1997,

10

Usa Path.GetFileNameWithoutExtension. Il percorso è nello spazio dei nomi System.IO.



6

Come risposta aggiuntiva (o da comporre sulle risposte esistenti) è possibile scrivere un metodo di estensione per farlo all'interno della classe DirectoryInfo. Ecco un esempio che ho scritto abbastanza rapidamente che potrebbe essere abbellito per fornire nomi di directory o altri criteri per la modifica, ecc:

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>();
         }
    }
}

Modifica: Penso anche che questo metodo potrebbe probabilmente essere semplificato o fantastico se usasse LINQ per realizzare la costruzione dell'array, ma non ho l'esperienza in LINQ per farlo abbastanza rapidamente per un campione di questo tipo.

Modifica 2 (quasi 4 anni dopo): ecco il metodo LINQ-ified che userei:

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

5

FileInfo conosce la propria estensione, quindi è possibile rimuoverlo

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

o se sei paranoico che potrebbe apparire nel mezzo o vuoi microottimizzare:

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

4

se il nome del file contiene directory e non devi perdere la directory:

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

2

prova questo,

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

1

Solo per la cronaca:

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

In questo modo non si usa StringBuilderma String.Join(). Inoltre, osserva che è Path.GetFileNameWithoutExtension()necessario un percorso completo ( fi.FullName), non fi.Namecome ho visto in una delle altre risposte.


-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
Non sembri essere consapevole che esiste già una classe Framework che fa questo per te.
Andrew Barber,

3
Inoltre, se qualcuno ha chiamato i propri file "Current.XLSFiles.xls" questo causerà problemi REALI.
Tom Padilla,

@ TomPadilla perché questo dovrebbe causare problemi?
Luca,

Perché questo metodo presenterebbe "Current.files" come nome del file. Perché ogni istanza di ".xls" verrebbe sostituita da "", inclusi quelli nel mezzo del nome.
Tom Padilla,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.