Отримання імен файлів без розширень


279

Отримуючи імена файлів у певній папці:

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

fi.Nameдає мені ім'я файлу з його розширенням: file1.txt, file2.txt, file3.txt.

Як я можу отримати імена файлів без розширень? ( file1, file2, file3)

Відповіді:


479

Ви можете використовувати Path.GetFileNameWithoutExtension:

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

Хоча я здивований, немає способу отримати це безпосередньо від FileInfo(або, принаймні, я не бачу цього).


7
А щоб отримати розширення (додати, наприклад, наприклад), використовуйте: Path.GetExtension (fileName);
Джастін

2
@Juzzz Це зручно, якщо ви працюєте з голою струною, але якщо у вас вже є об'єкт FileInfo, не потрібно заважати Path. FileInfo вже забезпечує властивість "Extension" для цієї мети.
jmbpiano

Я отримав помилку "" будівельник "не існує в поточному контексті". Я додав "system.Text", але все-таки отримав таку ж помилку. В чому причина?
ffttyy

@ffttyy builderбуде примірником StringBuilderкоду ОП. Це лише приклад використання GetFileNameWithoutExtension - ви, ймовірно, краще будете написати власний код, який його викликає.
Rup

9
Тут слід зазначити, що якщо ваш файл містить подвійне розширення, GetFileNameWithoutExtensionвін видаляє лише кінцеве розширення. Наприклад, ім'я файлу example.es6.jsстанеexample.es6
Девід Робертс

48

Використовуйте Path.GetFileNameWithoutExtension().


Зверніть увагу, що Path.GetFileNameWithoutExtension - це не найкращий спосіб, оскільки він перевіряє недійсні символи шляху і намагається витягнути DirectorySeparatorChar, AltDirectorySeparatorChar або VolumeSeparatorChar у циклі, який, здається, не потрібен для імен файлів (не повний шлях)!
S.Serpooshan

22

Це рішення також перешкоджає додаванню кома в кінці.

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

Мені не подобається DirectoryInfo, FileInfo за цей сценарій.

DirectoryInfo та FileInfo збирають більше даних про папку та файли, ніж потрібно, щоб вони забирали більше часу та пам'яті, ніж потрібно.


2
+1. Я також віддаю перевагу Directory.GetFilesв будь-який день DirectoryInfo.GetFiles, якщо все, що я хочу, це імена файлів.
Йогеш

Мені це подобається, тому що String.Join, LINQ, немає StringBuilder.
Csaba Toth

Якщо ви подивитеся на вихідний код. Конструктор FileInfo має дуже малу вагу. А вся інформація, яку ви бачите, робиться за допомогою властивостей. Вони збираються лише тоді, коли ви їм зателефонуєте
fjch1997

@ fjch1997 - Конструктор дійсно викликає Path.GetFileName і перевіряє дозволи. Тож це здається трохи зайвим.
Ерно

@ErnodeWeerd FileIOPermission не перевіряє дозвіл на ACL. натомість це якийсь механізм в .NET для перевірки дозволу на частково довірений код. Отже, він не повинен робити жодного фактичного дзвінка IO. Наскільки це впливає на продуктивність? я не можу сказати без тестування. Але я припускаю, що це не так вже й здорово
fjch1997

10

Використовуйте Path.GetFileNameWithoutExtension. Шлях знаходиться у просторі імен System.IO.


10
Path.GetFileNameWithoutExtension(file);

Це повертає ім'я файлу лише без типу розширення. Ви також можете змінити його, щоб отримати і ім’я, і тип файлу

 Path.GetFileName(FileName);

джерело: https://msdn.microsoft.com/en-us/library/system.io.path(v=vs.110).aspx


Спасибі, найкраща відповідь - це завжди найкоротша відповідь.
Ашраф Абусада

6

В якості додаткової відповіді (або для складання існуючих відповідей) ви можете написати метод розширення, щоб досягти цього для вас у класі DirectoryInfo. Ось зразок, який я написав досить швидко, який міг би бути прикрашений для надання назв каталогів або інших критеріїв модифікації тощо:

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

Редагувати: Я також вважаю, що цей метод, ймовірно, може бути спрощений або надзвичайно пом'якшений, якби він використовував LINQ для досягнення побудови масиву, але у мене немає досвіду роботи в LINQ, щоб зробити це досить швидко для вибірки такого типу.

Редагувати 2 (майже 4 роки пізніше): Ось я використовував би метод LINQ:

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

5

FileInfo знає власне розширення, тому ви можете просто його видалити

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

або якщо ви параноїдальні, що може з’явитися посередині, або ви хочете мікрооптимізувати:

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

4

якщо ім'я файлу містить каталог, і вам не потрібно втрачати каталог:

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

2

спробуйте це,

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

1

Просто для запису:

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

Таким чином ви не використовуєте, StringBuilderале String.Join(). Також зауважте, що Path.GetFileNameWithoutExtension()потрібен повний шлях ( fi.FullName), а не fi.Nameяк я бачив в одній з інших відповідей.


-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
Ви, здається, не знаєте, що вже існує клас Framework, який робить це для вас.
Ендрю Барбер

3
Крім того, якщо хтось назвав свої файли "Current.XLSFiles.xls", це спричинить реальні проблеми.
Том Паділья

@TomPadilla, чому це може спричинити проблеми?
Лука101

Тому що цей метод буде представляти "Current.files" як ім'я файлу. Тому що кожен екземпляр ".xls" буде замінений на "", включаючи ті, що знаходяться в середині імені.
Том Паділья
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.