Pobieranie nazw plików bez rozszerzeń


279

Podczas pobierania nazw plików w określonym folderze:

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

fi.NameDaje mi nazwę pliku z rozszerzeniem jej: file1.txt, file2.txt, file3.txt.

Jak mogę uzyskać nazwy plików bez rozszerzeń? ( file1, file2, file3)

Odpowiedzi:


479

Możesz użyć Path.GetFileNameWithoutExtension:

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

Chociaż jestem zaskoczony, nie ma sposobu, aby uzyskać to bezpośrednio z FileInfo(lub przynajmniej nie widzę tego).


7
Aby uzyskać rozszerzenie (na przykład dodać później), użyj: Path.GetExtension (fileName);
Justin

2
@Juzzz Jest to przydatne, jeśli pracujesz z czystym ciągiem, ale jeśli masz już obiekt FileInfo, nie musisz martwić się ścieżką. FileInfo już udostępnia do tego celu właściwość „Extension”.
jmbpiano

Wystąpił błąd „„ Konstruktor ”nie istnieje w bieżącym kontekście”. Dodałem „system.Text”, ale nadal mam ten sam błąd. Jaki jest powód?
ffttyy

@ffttyy builderbędzie instancją StringBuilderw kodzie OP. Jest to tylko przykładowe zastosowanie GetFileNameWithoutExtension - prawdopodobnie lepiej będzie napisać własny kod, który go wywołuje.
Rup

9
Należy zauważyć, że jeśli plik zawiera podwójne rozszerzenie, GetFileNameWithoutExtensionusuwa tylko rozszerzenie końcowe . Na przykład nazwa pliku example.es6.jszostanie zmienionaexample.es6
David Roberts

48

Zauważ, że Path.GetFileNameWithoutExtension nie jest najlepszym sposobem, ponieważ sprawdza niepoprawne znaki ścieżki i próbuje wyodrębnić DirectorySeparatorChar, AltDirectorySeparatorChar lub VolumeSeparatorChar w pętli, która wydaje się nie konieczna dla nazw plików (nie pełna ścieżka)!
S.Serpooshan

22

To rozwiązanie zapobiega również dodaniu przecinka końcowego.

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

Nie lubię DirectoryInfo, FileInfo w tym scenariuszu.

DirectoryInfo i FileInfo zbierają więcej danych o folderze i plikach, niż jest to potrzebne, więc zajmują więcej czasu i pamięci, niż to konieczne.


2
+1. Ja też wolę Directory.GetFilesnad DirectoryInfo.GetFilesAnyday, jeśli wszystko czego chcę to nazwy plików.
Jogesh

Podoba mi się to, ponieważ String.Join, LINQ, bez StringBuilder.
Csaba Toth,

Jeśli spojrzysz na kod źródłowy. Konstruktor FileInfo jest bardzo lekki. A wszystkie informacje, które widzisz, są wykonywane za pośrednictwem właściwości. Są one gromadzone tylko wtedy, gdy do nich zadzwonisz
fjch1997,

@ fjch1997 - Konstruktor wywołuje Path.GetFileName i sprawdza uprawnienia. To wydaje się trochę zbędne.
Erno,

@ErnodeWeerd FileIOPermission nie sprawdza uprawnień na liście ACL. zamiast tego jest to jakiś mechanizm w .NET do sprawdzania uprawnień dla częściowo zaufanego kodu. Tak więc nie powinien wykonywać żadnego rzeczywistego połączenia We / Wy. Jak bardzo wpływa na wydajność? nie mogę powiedzieć bez testowania. Ale zakładam, że to nie jest takie świetne
fjch1997,

10

Zastosowanie Path.GetFileNameWithoutExtension. Ścieżka znajduje się w przestrzeni nazw System.IO.



6

Jako dodatkową odpowiedź (lub jako uzupełnienie istniejących odpowiedzi) możesz napisać metodę rozszerzenia, aby to zrobić za Ciebie w klasie DirectoryInfo. Oto przykład, który napisałem dość szybko, który można upiększyć, aby podać nazwy katalogów lub inne kryteria modyfikacji itp .:

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

Edycja: Myślę również, że ta metoda mogłaby być prawdopodobnie uproszczona lub niesamowita, gdyby użyła LINQ do uzyskania konstrukcji tablicy, ale nie mam doświadczenia w LINQ, aby zrobić to wystarczająco szybko dla próbki tego rodzaju.

Edytuj 2 (prawie 4 lata później): Oto metoda LINQ-ified, której chciałbym użyć:

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

5

FileInfo zna własne rozszerzenie, więc możesz je po prostu usunąć

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

lub jeśli jesteś paranoikiem, że może pojawić się w środku lub chcesz mikrooptymalizować:

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

4

jeśli nazwa pliku zawiera katalog i nie musisz stracić katalogu:

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

2

Spróbuj tego,

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

1

Dla przypomnienia:

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

W ten sposób nie używasz, StringBuilderale String.Join(). Proszę również zauważyć, że Path.GetFileNameWithoutExtension()potrzebuje pełnej ścieżki ( fi.FullName), a nie fi.Namejak widziałem w jednej z pozostałych odpowiedzi.


-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
Nie zdajesz sobie sprawy, że istnieje już klasa Framework, która robi to za Ciebie.
Andrew Barber,

3
Ponadto, jeśli ktoś nazwie swoje pliki „Current.XLSFiles.xls”, spowoduje to PRAWDZIWE problemy.
Tom Padilla

@TomPadilla dlaczego miałoby to powodować problemy?
Luke101,

Ponieważ ta metoda przedstawiłaby „Current.files” jako nazwę pliku. Ponieważ każde wystąpienie „.xls” zostanie zastąpione przez „”, w tym te w środku nazwy.
Tom Padilla,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.