Como obtenho o nome do arquivo de uma String contendo o caminho do arquivo Absoluto?

236

StringA variável contém um nome de arquivo C:\Hello\AnotherFolder\The File Name.PDF. Como obtenho apenas o nome do arquivo The File Name.PDFcomo uma String?

Planejei dividir a string, mas essa não é a solução ideal.

sharon Hwk
fonte
com referência a issuetracker.google.com/issues/37131215 , foi corrigido.
Prags

Respostas:

280

basta usar File.getName ()

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

usando métodos String :

  File f = new File("C:\\Hello\\AnotherFolder\\The File Name.PDF");  
System.out.println(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\")+1));
PermGenError
fonte
Útil. Obrigado.
Pooja
Cuidado com nomes de caminhos com "/" em vez de "\"
golimar
278

Uso alternativo Path(Java 7+):

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

Observe que a divisão da sequência \\depende da plataforma, pois o separador de arquivos pode variar. Path#getNamecuida desse problema para você.

assilias
fonte
1
Alguém fez uma comparação de desempenho nos vários métodos desta pergunta?
esmagar
@crush Eu não acho que Paths.getacesse o sistema de arquivos, então não esperaria que o desempenho fosse materialmente diferente de um substring / indexOf.
assylias 26/09/13
7
Por que ele não existe no Android? esquisito.
desenvolvedor android
12
Sim, o Path lida com o problema dependente da plataforma de barra / barra invertida, mas apenas se o caminho do arquivo for da mesma máquina (ou plataforma). Considere o seguinte: você faz o upload do arquivo Internet Explorere ele possui o caminho, "C:\\Hello\\AnotherFolder\\The File Name.PDF"mas seu código está funcionando em uma máquina Unix / Linux e, em seguida p.getFileName(), retornará o caminho inteiro, não apenas The File Name.PDF.
Nyxz
3
Ligar toString()é tão estranho.
PetroCliff
53

Usando FilenameUtilsno Apache Commons IO :

String name1 = FilenameUtils.getName("/ab/cd/xyz.txt");
String name2 = FilenameUtils.getName("c:\\ab\\cd\\xyz.txt");
Binoy Babu
fonte
5
Eu acho que este pode ser o melhor, porque às vezes você pode ter que processar o caminho do arquivo de outra plataforma
ruiruige1991
Este é o melhor porque: Fácil de ler, mais robusto e com menos objetos cludder no código +1
fl0w 26/03
32

Considerando o que Stringvocê está perguntando é

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

precisamos extrair tudo após o último separador, ie. \. É nisso que estamos interessados.

Você pode fazer

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

Isso recuperará o índice do último \no seu Stringe extrairá tudo o que vier depois dele fileName.

Se você tiver um Stringseparador diferente, ajuste lastIndexOfpara usar esse separador. (Existe até uma sobrecarga que aceita um inteiro Stringcomo separador.)

Omiti-o no exemplo acima, mas se você não souber de onde Stringvem ou o que pode conter, você deve validar que o valor lastIndexOfretornado não é negativo porque o Javadoc declara que retornará

-1 se não houver tal ocorrência

Sotirios Delimanolis
fonte
25

Desde 1,7

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

você pode usar o caminho = C: \ Hello \ AnotherFolder \ TheFileName.PDF

String strPath = path.substring(path.lastIndexOf("\\")+1, path.length());
Rakesh
fonte
Você deve usar \\ em vez de \
Anoop Chandrika HarisudhanNair
2
Você não deve usar nenhum deles, pois depende da plataforma. /no unix e \`(AND THERE IS A BUG IN THE MARKDOWN PARSER HERE) on windows. You can't know. Use another solution like File` ou Paths.
Automatico
3
File.separatorTambém é dependente da plataforma? Ou será que esse trabalho ... String strPath = path.substring(path.lastIndexOf(File.separator)+1, path.length());
Jonathan
File.separator e File.separatorChar são "/" na versão UNIX / Linux / macOS do JDK e "\" na versão Windows.
賈可Jacky
2
File.separatornem sempre funcionará aqui porque no Windows um nome de arquivo pode ser separado por um "/"ou outro "\\".
DodgyCodeException 23/11
10

As outras respostas não funcionaram no meu cenário específico, onde estou lendo caminhos que se originaram de um SO diferente do atual. Para elaborar, estou salvando anexos de email salvos de uma plataforma Windows em um servidor Linux. O nome do arquivo retornado da API JavaMail é algo como 'C: \ temp \ hello.xls'

A solução que eu acabei com:

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

Considere o caso de que Java é multiplataforma:

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

Um método sem dependência e cuida de ... , . e 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 teste:

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

Talvez getFileName seja um pouco confuso, porque também retorna nomes de diretório. Retorna o nome do arquivo ou último diretório em um caminho.

yavuzkavus
fonte
0

extrair o nome do arquivo 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
fonte
0

Você pode usar o objeto FileInfo para obter todas as informações do seu arquivo.

    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);
Blue Phoenix
fonte