Получение имен файлов без расширений


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в коде OP. Это просто пример использования GetFileNameWithoutExtension - вам, скорее всего, лучше будет написать собственный код, который его вызывает.
Rup

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

48

Использование Path.GetFileNameWithoutExtension().


Обратите внимание, что Path.GetFileNameWithoutExtension - не лучший способ, так как он проверяет наличие недопустимых символов пути и пытается извлечь DirectorySeparatorChar, AltDirectorySeparatorChar или VolumeSeparatorChar в цикле, который кажется необязательным для имен файлов (не полных путей)!
С.Серпушан

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.
Чаба Тот

Если вы посмотрите на исходный код. Конструктор 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-ified, который я бы использовал:

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("."))


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, почему это может вызвать проблемы?
Luke101

Потому что этот метод будет представлять «Current.files» в качестве имени файла. Потому что каждый экземпляр ".xls" будет заменен на "", в том числе в середине имени.
Том Падилья
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.