¿Cómo obtengo el nombre del archivo de una cadena que contiene la ruta absoluta del archivo?

237

Stringvariable contiene un nombre de archivo, C:\Hello\AnotherFolder\The File Name.PDF. ¿Cómo obtengo solo el nombre del archivo The File Name.PDFcomo una cadena?

Planeaba dividir la cadena, pero esa no es la solución óptima.

Sharon Hwk
fuente
con referencia a issuetracker.google.com/issues/37131215 , se ha solucionado.
Prags

Respuestas:

281

solo use File.getName ()

File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");
System.out.println(f.getName());

utilizando métodos de cadena :

  File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");  
System.out.println(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\")+1));
PermGenError
fuente
Servicial. Gracias.
Pooja
Tenga cuidado con los nombres de ruta con "/" en lugar de "\"
golimar
278

Uso alternativo Path(Java 7+):

Path p = Paths.get("C:\\Hello\\AnotherFolder\\The File Name.PDF");
String file = p.getFileName().toString();

Tenga en cuenta que dividir la cadena \\depende de la plataforma, ya que el separador de archivos puede variar. Path#getNamese encarga de ese problema por ti.

asilias
fuente
1
¿Alguien ha hecho una comparación de rendimiento en los diversos métodos en esta pregunta?
aplastar
@crush No creo que Paths.getacceda al sistema de archivos, por lo que no esperaría que el rendimiento sea materialmente diferente de una subcadena / indexOf.
Assylias
77
¿Cómo es que no existe en Android? extraño.
Desarrollador de Android
12
Sí, Path hace frente al problema de barra diagonal / barra diagonal inversa dependiente de la plataforma, pero solo si la ruta del archivo es de la misma máquina (o plataforma). Considere esto: carga el archivo Internet Explorery tiene la ruta, "C:\\Hello\\AnotherFolder\\The File Name.PDF"pero su código está funcionando en una máquina Unix / Linux y luego p.getFileName()devolverá la ruta completa, no solo The File Name.PDF.
nyxz
3
Llamar toString()es muy incómodo.
PetroCliff
53

Utilizando FilenameUtilsen Apache Commons IO :

String name1 = FilenameUtils.getName("/ab/cd/xyz.txt");
String name2 = FilenameUtils.getName("c:\\ab\\cd\\xyz.txt");
Binoy Babu
fuente
55
Creo que este puede ser el mejor, porque a veces puede que tenga que procesar la ruta del archivo desde otra plataforma
ruiruige1991
Este es el mejor porque: Fácil de leer, más robusto, menos agrupamiento de objetos en el código +1
fl0w
32

Teniendo en cuenta lo Stringque estás preguntando es

C:\Hello\AnotherFolder\The File Name.PDF

necesitamos extraer todo después del último separador, es decir. \. Eso es lo que nos interesa.

Tu puedes hacer

String fullPath = "C:\\Hello\\AnotherFolder\\The File Name.PDF";
int index = fullPath.lastIndexOf("\\");
String fileName = fullPath.substring(index + 1);

Esto recuperará el índice del último \en su Stringy extraerá todo lo que viene después fileName.

Si tiene un Stringseparador diferente, ajuste el lastIndexOfpara usar ese separador. (Incluso hay una sobrecarga que acepta un todo Stringcomo separador).

Lo he omitido en el ejemplo anterior, pero si no está seguro de dónde Stringproviene o qué podría contener, querrá validar que lastIndexOfdevuelve un valor no negativo porque el Javadoc indica que devolverá

-1 si no hay tal ocurrencia

Sotirios Delimanolis
fuente
25

Desde 1.7

    Path p = Paths.get("c:\\temp\\1.txt");
    String fileName = p.getFileName().toString();
    String directory = p.getParent().toString();
max3d
fuente
11

puede usar path = C: \ Hello \ AnotherFolder \ TheFileName.PDF

String strPath = path.substring(path.lastIndexOf("\\")+1, path.length());
Rakesh
fuente
Debería usar \\ en lugar de \
Anoop Chandrika HarisudhanNair
2
No debe usar ninguno de ellos, ya que depende de la plataforma. /en unix y \`(AND THERE IS A BUG IN THE MARKDOWN PARSER HERE) on windows. You can't know. Use another solution like File` o Paths.
Automático
3
¿ File.separatorTambién depende de la plataforma? ¿O esto funcionaría ... String strPath = path.substring(path.lastIndexOf(File.separator)+1, path.length());
Jonathan
File.separator y File.separatorChar son "/" en la versión UNIX / Linux / macOS de JDK, y ambos "\" en la versión de Windows.
賈 可 Jacky
2
File.separatorno siempre funcionará aquí porque en Windows un nombre de archivo se puede separar con "/"o "\\".
DodgyCodeException
10

Las otras respuestas no funcionaron para mi escenario específico, donde estoy leyendo rutas que se han originado desde un sistema operativo diferente al actual. Para elaborar, estoy guardando archivos adjuntos de correo electrónico guardados desde una plataforma Windows en un servidor Linux. El nombre de archivo devuelto por la API JavaMail es algo así como 'C: \ temp \ hello.xls'

La solución que terminé con:

String filenameWithPath = "C:\\temp\\hello.xls";
String[] tokens = filenameWithPath.split("[\\\\|/]");
String filename = tokens[tokens.length - 1];
javaPhobic
fuente
3

Considere el caso de que Java es multiplataforma:

int lastPath = fileName.lastIndexOf(File.separator);
if (lastPath!=-1){
    fileName = fileName.substring(lastPath+1);
}
Alejandro Hdz
fuente
1

Un método sin ninguna dependencia y se encarga de ... , . y separadores duplicados.

public static String getFileName(String filePath) {
    if( filePath==null || filePath.length()==0 )
        return "";
    filePath = filePath.replaceAll("[/\\\\]+", "/");
    int len = filePath.length(),
        upCount = 0;
    while( len>0 ) {
        //remove trailing separator
        if( filePath.charAt(len-1)=='/' ) {
            len--;
            if( len==0 )
                return "";
        }
        int lastInd = filePath.lastIndexOf('/', len-1);
        String fileName = filePath.substring(lastInd+1, len);
        if( fileName.equals(".") ) {
            len--;
        }
        else if( fileName.equals("..") ) {
            len -= 2;
            upCount++;
        }
        else {
            if( upCount==0 )
                return fileName;
            upCount--;
            len -= fileName.length();
        }
    }
    return "";
}

Caso de prueba:

@Test
public void testGetFileName() {
    assertEquals("", getFileName("/"));
    assertEquals("", getFileName("////"));
    assertEquals("", getFileName("//C//.//../"));
    assertEquals("", getFileName("C//.//../"));
    assertEquals("C", getFileName("C"));
    assertEquals("C", getFileName("/C"));
    assertEquals("C", getFileName("/C/"));
    assertEquals("C", getFileName("//C//"));
    assertEquals("C", getFileName("/A/B/C/"));
    assertEquals("C", getFileName("/A/B/C"));
    assertEquals("C", getFileName("/C/./B/../"));
    assertEquals("C", getFileName("//C//./B//..///"));
    assertEquals("user", getFileName("/user/java/.."));
    assertEquals("C:", getFileName("C:"));
    assertEquals("C:", getFileName("/C:"));
    assertEquals("java", getFileName("C:\\Program Files (x86)\\java\\bin\\.."));
    assertEquals("C.ext", getFileName("/A/B/C.ext"));
    assertEquals("C.ext", getFileName("C.ext"));
}

Quizás getFileName es un poco confuso, porque también devuelve nombres de directorio. Devuelve el nombre del archivo o el último directorio en una ruta.

yavuzkavus
fuente
0

extraer el nombre del archivo usando java regex *.

public String extractFileName(String fullPathFile){
        try {
            Pattern regex = Pattern.compile("([^\\\\/:*?\"<>|\r\n]+$)");
            Matcher regexMatcher = regex.matcher(fullPathFile);
            if (regexMatcher.find()){
                return regexMatcher.group(1);
            }
        } catch (PatternSyntaxException ex) {
            LOG.info("extractFileName::pattern problem <"+fullPathFile+">",ex);
        }
        return fullPathFile;
    }
HJK
fuente
0

Puede usar el objeto FileInfo para obtener toda la información de su archivo.

    FileInfo f = new FileInfo(@"C:\Hello\AnotherFolder\The File Name.PDF");
    MessageBox.Show(f.Name);
    MessageBox.Show(f.FullName);
    MessageBox.Show(f.Extension );
    MessageBox.Show(f.DirectoryName);
Fénix azul
fuente