Obtendo nomes de arquivos sem extensões


279

Ao obter nomes de arquivos em uma determinada pasta:

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

fi.Nameme dá um nome de arquivo com sua extensão: file1.txt, file2.txt, file3.txt.

Como posso obter os nomes dos arquivos sem as extensões? ( file1, file2, file3)

Respostas:


479

Você pode usar Path.GetFileNameWithoutExtension:

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

Embora eu esteja surpreso, não há como obtê-lo diretamente do FileInfo(ou pelo menos não consigo vê-lo).


7
E para obter a extensão (para adicionar mais tarde, por exemplo), use: Path.GetExtension (fileName);
Justin

2
@Juzzz Isso é útil se você estiver trabalhando com uma string simples, mas se você já tiver um objeto FileInfo, não há necessidade de se preocupar com o Path. O FileInfo já fornece a propriedade "Extensão" para esse fim.
jmbpiano

Eu recebi o erro "'construtor' não existe no contexto atual". Eu adicionei 'system.Text', mas ainda tenho o mesmo erro. Qual é a razão?
precisa saber é

@ffttyy builderserá uma instância StringBuilderdo código do OP. É apenas um exemplo de uso de GetFileNameWithoutExtension - você provavelmente fará melhor escrevendo seu próprio código que o chama.
Rup

9
Uma dica a observar aqui é que, se o seu arquivo contiver uma extensão dupla, GetFileNameWithoutExtensionapenas a extensão final será removida . Por exemplo, o nome do arquivo example.es6.jsse tornaráexample.es6
David Roberts


22

Essa solução também evita a adição de uma vírgula à direita.

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

Não gosto do DirectoryInfo, FileInfo para este cenário.

DirectoryInfo e FileInfo coletam mais dados sobre a pasta e os arquivos do que o necessário, para que eles levem mais tempo e memória do que o necessário.


2
+1. Eu também prefiro Directory.GetFileso DirectoryInfo.GetFilesdia todo, se tudo que eu quero são nomes de arquivos.
Yogesh

Eu gosto disso porque String.Join, LINQ, no StringBuilder.
Csaba Toth #

Se você der uma olhada no código fonte. O construtor do FileInfo é muito leve. E todas as informações que você vê são feitas através de propriedades. Eles só estão reunidas quando você os chama
fjch1997

@ fjch1997 - O construtor chama Path.GetFileName e verifica as permissões. Então isso parece um pouco redundante.
quer

O @ErnodeWeerd FileIOPermission não verifica a permissão na ACL. em vez disso, é algum tipo de mecanismo no .NET para verificar a permissão de código parcialmente confiável. Portanto, não deve fazer nenhuma ligação IO real. Quanto isso afeta o desempenho? Eu não posso dizer sem testar. Mas presumo que não é tão grande
fjch1997

10

Use Path.GetFileNameWithoutExtension. O caminho está no espaço para nome System.IO.



6

Como resposta adicional (ou para complementar as respostas existentes), você pode escrever um método de extensão para fazer isso dentro da classe DirectoryInfo. Aqui está um exemplo que escrevi rapidamente, que pode ser embelezado para fornecer nomes de diretório ou outros critérios para modificação, etc:

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

Edit: Eu também acho que esse método provavelmente poderia ser simplificado ou impressionante se usasse o LINQ para conseguir a construção da matriz, mas não tenho a experiência no LINQ para fazê-lo com rapidez suficiente para uma amostra desse tipo.

Editar 2 (quase 4 anos depois): Aqui está o método LINQ-ified que eu usaria:

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

5

FileInfo conhece sua própria extensão, então você pode removê-la

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

ou se você estiver paranóico, pode aparecer no meio ou deseja otimizar:

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

4

se o nome do arquivo contiver o diretório e você não precisar perder o diretório:

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

2

tente isso,

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

1

Apenas para o registro:

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

Desta forma, você não usa, StringBuildermas String.Join(). Observe também que Path.GetFileNameWithoutExtension()precisa de um caminho completo ( fi.FullName), não fi.Namecomo vi em uma das outras respostas.


-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
Você não parece estar ciente de que já existe uma classe Framework que faz isso por você.
Andrew Barber

3
Além disso, se alguém nomear seus arquivos "Current.XLSFiles.xls", isso causará problemas reais.
Tom Padilla

@ TomPadilla Por que isso causaria problemas?
Luke101

Porque esse método apresentaria "Current.files" como o nome do arquivo. Porque cada instância de ".xls" seria substituída por "", incluindo aquelas no meio do nome.
Tom Padilla
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.