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)

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


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

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.


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.



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

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)

4

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

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

2

prueba esto,

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

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.


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

    }

}

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.