Obtener nombres de archivo sin extensiones

279

Al obtener nombres de archivos en una carpeta determinada:

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

fi.Nameme da un nombre de archivo con su extensión: file1.txt, file2.txt, file3.txt.

¿Cómo puedo obtener los nombres de archivo sin las extensiones? ( file1` file2` file3)

movimiento rápido del ojo
fuente

Respuestas:

479

Puedes usar Path.GetFileNameWithoutExtension:

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

Aunque estoy sorprendido de que no haya una forma de obtener esto directamente del FileInfo(o al menos no puedo verlo).

Rup
fuente
77
Y para obtener la extensión (para agregar más tarde, por ejemplo) use: Path.GetExtension (fileName);
Justin
2
@Juzzz Eso es útil si está trabajando con una cadena desnuda, pero si ya tiene un objeto FileInfo, no hay necesidad de molestarse con Path. FileInfo ya proporciona la propiedad "Extensión" para este propósito.
jmbpiano
Obtuve el error "'constructor' no existe en el contexto actual". Agregué 'system.Text' pero aún recibí el mismo error. ¿Cuál es la razón?
ffttyy
@ffttyy builderserá una instancia StringBuilderen el código del OP. Es solo un ejemplo de uso de GetFileNameWithoutExtension: probablemente será mejor escribir su propio código que lo llame.
Rup
9
Una cosa que debes tener en cuenta aquí es que si tu archivo contiene una extensión doble, GetFileNameWithoutExtensionsolo elimina la extensión final . Por ejemplo, el nombre del archivo example.es6.jsse convertiráexample.es6
David Roberts
48

Uso Path.GetFileNameWithoutExtension().

Marcel Gheorghita
fuente
Tenga en cuenta que Path.GetFileNameWithoutExtension no es la mejor manera, ya que busca caracteres de ruta no válidos e intenta extraer DirectorySeparatorChar, AltDirectorySeparatorChar o VolumeSeparatorChar en un bucle que parece no necesario para los nombres de archivo (no la ruta completa).
S.Serpooshan
22

Esta solución también evita la adición de una coma final.

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

No me gusta DirectoryInfo, FileInfo para este escenario.

DirectoryInfo y FileInfo recopilan más datos sobre la carpeta y los archivos de los necesarios, por lo que requieren más tiempo y memoria de lo necesario.

Erno
fuente
2
+1. También prefiero Directory.GetFilesa cualquier día DirectoryInfo.GetFiles, si todo lo que quiero son nombres de archivo.
Yogesh
Me gusta esto porque String.Join, LINQ, no StringBuilder.
Csaba Toth
Si echas un vistazo al código fuente. El constructor de FileInfo es muy ligero. Y toda la información que ve se realiza a través de propiedades. Sólo se recogen cuando se les llama
fjch1997
@ fjch1997: el constructor llama a Path.GetFileName y verifica los permisos. Entonces eso parece un poco redundante.
Erno
@ErnodeWeerd FileIOPermission no verifica el permiso contra la ACL. en cambio, es algún tipo de mecanismo en .NET para verificar el permiso de código parcialmente confiable. Por lo tanto, no debería hacer ninguna llamada real de IO. ¿Cuánto afecta el rendimiento? No puedo decir sin probar. Pero supongo que no es tan genial
fjch1997
10

Uso Path.GetFileNameWithoutExtension. La ruta está en el espacio de nombres System.IO.

Pradeep
fuente
10
Path.GetFileNameWithoutExtension(file);

Esto devuelve el nombre del archivo solo sin el tipo de extensión. También puede cambiarlo para obtener tanto el nombre como el tipo de archivo

 Path.GetFileName(FileName);

fuente: https://msdn.microsoft.com/en-us/library/system.io.path(v=vs.110).aspx

Chong Ching
fuente
Gracias, la mejor respuesta es siempre la respuesta más corta.
Ashraf Abusada
6

Como respuesta adicional (o para componer las respuestas existentes), podría escribir un método de extensión para lograr esto dentro de la clase DirectoryInfo. Aquí hay una muestra que escribí con bastante rapidez que podría ser embellecida para proporcionar nombres de directorio u otros criterios de modificación, 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>();
         }
    }
}

Editar: también creo que este método probablemente podría simplificarse o hacerse increíble si usara LINQ para lograr la construcción de la matriz, pero no tengo la experiencia en LINQ para hacerlo lo suficientemente rápido para una muestra de este tipo.

Edición 2 (casi 4 años después): Aquí está el método LINQ-ified que usaría:

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

FileInfo conoce su propia extensión, por lo que podría eliminarla

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

o si eres paranoico de que pueda aparecer en el medio, o si quieres microoptimizar:

file.Name.Substring(0, file.Name.Length - file.Extension.Length)
drzaus
fuente
4

si el nombre del archivo contiene el directorio y no necesita perder el directorio:

fileName.Remove(fileName.LastIndexOf("."))
Omid-RH
fuente
2

prueba esto,

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

Para que conste:

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

De esta manera no usas StringBuilderpero String.Join(). También tenga en cuenta que Path.GetFileNameWithoutExtension()necesita una ruta completa ( fi.FullName), no fi.Namecomo vi en una de las otras respuestas.

Papuashu
fuente
-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();

    }

}
Tisho
fuente
55
No parece ser consciente de que ya existe una clase Framework que hace esto por usted.
Andrew Barber
3
Además, si alguien llamó a sus archivos "Current.XLSFiles.xls", esto causará problemas REALES.
Tom Padilla
@ TomPadilla ¿por qué esto causaría problemas?
Luke101
Porque este método presentaría "Current.files" como el nombre del archivo. Porque cada instancia de ".xls" se reemplazaría con "", incluidas las que están en el medio del nombre.
Tom Padilla