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.