Obter nome do arquivo do URL

146

Em Java, dado a java.net.URLou a Stringna forma de http://www.example.com/some/path/to/a/file.xml, qual é a maneira mais fácil de obter o nome do arquivo, menos a extensão? Então, neste exemplo, estou procurando por algo que retorne "file".

Posso pensar em várias maneiras de fazer isso, mas estou procurando algo que seja fácil de ler e breve.

Sietse
fonte
3
VOCÊ percebe que não é necessário que exista um nome de arquivo no final, ou mesmo algo que se pareça com um nome de arquivo. Nesse caso, pode ou não haver um file.xml no servidor.
Variável miserável 03/03
2
nesse caso, o resultado seria uma string vazia ou talvez nula.
Sietse 03/03/09
1
Eu acho que você precisa definir o problema mais claramente. E as seguintes terminações de URLS? .... / abc, .... / abc /, .... / abc.def, .... / abc.def.ghi, .... / abc? def.ghi
Variável miserável
2
Eu acho que é bem claro. Se o URL apontar para um arquivo, estou interessado no nome do arquivo menos a extensão (se houver). As peças da consulta ficam fora do nome do arquivo.
Sietse
4
o nome do arquivo é a parte do URL após a última barra. a extensão do arquivo é a parte do nome do arquivo após o último período.
Sietse

Respostas:

188

Em vez de reinventar a roda, que tal usar o Apache commons-io :

import org.apache.commons.io.FilenameUtils;

public class FilenameUtilTest {

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://www.example.com/some/path/to/a/file.xml?foo=bar#test");

        System.out.println(FilenameUtils.getBaseName(url.getPath())); // -> file
        System.out.println(FilenameUtils.getExtension(url.getPath())); // -> xml
        System.out.println(FilenameUtils.getName(url.getPath())); // -> file.xml
    }

}
Adrian B.
fonte
2
Na versão commons-io 2.2, pelo menos você ainda precisa manipular URLs manualmente com parâmetros. Por exemplo, " example.com/file.xml?date=2010-10-20 "
Luke Quinane 13/08/2013
18
FilenameUtils.getName (url) é mais adequado.
precisa saber é o seguinte
4
Parece estranho adicionar uma dependência do commons-io quando soluções fáceis estão prontamente disponíveis apenas usando o JDK (consulte URL#getPathe String#substringou Path#getFileNameou File#getName).
Jason C
5
A classe FilenameUtils foi projetada para funcionar com o Windows e o caminho * nix, não com o URL.
Nhahtdh 29/07
4
Exemplo atualizado para usar uma URL, mostrar valores de saída de amostra e usar parâmetros de consulta.
Nick Grealy
191
String fileName = url.substring( url.lastIndexOf('/')+1, url.length() );

String fileNameWithoutExtn = fileName.substring(0, fileName.lastIndexOf('.'));
Vermelho real.
fonte
17
Por que o voto negativo? Isso é injusto. Meu código funciona, eu apenas verifiquei meu código depois de ver o voto negativo.
vermelho real.
2
Eu votei em você, porque é um pouco mais legível que a minha versão. O voto negativo pode ser porque não funciona quando não há extensão ou arquivo.
Sietse 03/03/2009
1
Você pode deixar o segundo parâmetro parasubstring()
Jon Onstott 6/12 de14
12
Isso não funciona para nem http://example.org/file#anchor, http://example.org/file?p=foo&q=barnemhttp://example.org/file.xml#/p=foo&q=bar
Matthias Ronge
2
Se você permitir String url = new URL(original_url).getPath()e adicionar um caso especial para nomes de arquivos que não contenham um ., isso funcionará bem.
Jason C
32

Se você não precisar se livrar da extensão do arquivo, aqui está uma maneira de fazê-lo sem recorrer à manipulação de String propensa a erros e sem usar bibliotecas externas. Funciona com Java 1.7+:

import java.net.URI
import java.nio.file.Paths

String url = "http://example.org/file?p=foo&q=bar"
String filename = Paths.get(new URI(url).getPath()).getFileName().toString()
Zoltán
fonte
1
@Carcigenicate Acabei de o testar novamente e parece funcionar bem. URI.getPath()retorna um String, então eu não vejo por que ele não iria funcionar
Zoltán
1
Nvm. Agora percebo que meu problema ocorreu devido a como o Clojure lida com var-args durante a interoperabilidade Java. A sobrecarga de String não estava funcionando porque uma matriz vazia também precisava ser passada para lidar com os var-args de Paths / get. Ainda funciona se você se livrar da chamada getPathe usar a sobrecarga de URI.
Carcigenicate
@Carcigenicate você quer dizer Paths.get(new URI(url))? Isso não parece trabalhar para mim
Zoltán
getFileName requer api android nível 26
Manuela
26

Isso deve ser resolvido (deixarei o tratamento de erros para você):

int slashIndex = url.lastIndexOf('/');
int dotIndex = url.lastIndexOf('.', slashIndex);
String filenameWithoutExtension;
if (dotIndex == -1) {
  filenameWithoutExtension = url.substring(slashIndex + 1);
} else {
  filenameWithoutExtension = url.substring(slashIndex + 1, dotIndex);
}
tehvan
fonte
1
Um erro aspecto manipulação você precisa considerar é que você vai acabar com uma seqüência vazia se você acidentalmente passar um url que não tenha um nome de arquivo (como http://www.example.com/ou http://www.example.com/folder/)
rtpHarry
2
O código não funciona. lastIndexOfnão funciona assim. Mas a intenção é clara.
Robert
Diminuiu o voto porque não funcionará se a parte do fragmento contiver barras, e porque existem funções dedicadas que conseguem isso no apache commons e no Java desde 1.7
Zoltán
14
public static String getFileName(URL extUrl) {
        //URL: "http://photosaaaaa.net/photos-ak-snc1/v315/224/13/659629384/s659629384_752969_4472.jpg"
        String filename = "";
        //PATH: /photos-ak-snc1/v315/224/13/659629384/s659629384_752969_4472.jpg
        String path = extUrl.getPath();
        //Checks for both forward and/or backslash 
        //NOTE:**While backslashes are not supported in URL's 
        //most browsers will autoreplace them with forward slashes
        //So technically if you're parsing an html page you could run into 
        //a backslash , so i'm accounting for them here;
        String[] pathContents = path.split("[\\\\/]");
        if(pathContents != null){
            int pathContentsLength = pathContents.length;
            System.out.println("Path Contents Length: " + pathContentsLength);
            for (int i = 0; i < pathContents.length; i++) {
                System.out.println("Path " + i + ": " + pathContents[i]);
            }
            //lastPart: s659629384_752969_4472.jpg
            String lastPart = pathContents[pathContentsLength-1];
            String[] lastPartContents = lastPart.split("\\.");
            if(lastPartContents != null && lastPartContents.length > 1){
                int lastPartContentLength = lastPartContents.length;
                System.out.println("Last Part Length: " + lastPartContentLength);
                //filenames can contain . , so we assume everything before
                //the last . is the name, everything after the last . is the 
                //extension
                String name = "";
                for (int i = 0; i < lastPartContentLength; i++) {
                    System.out.println("Last Part " + i + ": "+ lastPartContents[i]);
                    if(i < (lastPartContents.length -1)){
                        name += lastPartContents[i] ;
                        if(i < (lastPartContentLength -2)){
                            name += ".";
                        }
                    }
                }
                String extension = lastPartContents[lastPartContentLength -1];
                filename = name + "." +extension;
                System.out.println("Name: " + name);
                System.out.println("Extension: " + extension);
                System.out.println("Filename: " + filename);
            }
        }
        return filename;
    }
Mike
fonte
13

Um forro:

new File(uri.getPath).getName

Código completo (em um scala REPL):

import java.io.File
import java.net.URI

val uri = new URI("http://example.org/file.txt?whatever")

new File(uri.getPath).getName
res18: String = file.txt

Nota : URI#gePathjá é inteligente o suficiente para remover os parâmetros de consulta e o esquema do protocolo. Exemplos:

new URI("http://example.org/hey/file.txt?whatever").getPath
res20: String = /hey/file.txt

new URI("hdfs:///hey/file.txt").getPath
res21: String = /hey/file.txt

new URI("file:///hey/file.txt").getPath
res22: String = /hey/file.txt
juanmirocks
fonte
1
boa solução!
CybeX 22/01/19
1
esta é a melhor opção, pois utiliza apenas JDK padrão
Alexandros
11

Obtenha o nome do arquivo com extensão , sem extensão , apenas extensão com apenas 3 linhas:

String urlStr = "http://www.example.com/yourpath/foler/test.png";

String fileName = urlStr.substring(urlStr.lastIndexOf('/')+1, urlStr.length());
String fileNameWithoutExtension = fileName.substring(0, fileName.lastIndexOf('.'));
String fileExtension = urlStr.substring(urlStr.lastIndexOf("."));

Log.i("File Name", fileName);
Log.i("File Name Without Extension", fileNameWithoutExtension);
Log.i("File Extension", fileExtension);

Resultado do log:

File Name(13656): test.png
File Name Without Extension(13656): test
File Extension(13656): .png

Espero que ajude você.

Hiren Patel
fonte
9

Eu vim com isso:

String url = "http://www.example.com/some/path/to/a/file.xml";
String file = url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.'));
Sietse
fonte
Ou em URLs sem arquivo, apenas um caminho.
Sietse 03/03/2009
seu código também está correto. não devemos verificar condições negativas de qualquer maneira. um voto positivo para você. btw o nome dirk kuyt soa familiar?
vermelho real.
7

Mantenha simples :

/**
 * This function will take an URL as input and return the file name.
 * <p>Examples :</p>
 * <ul>
 * <li>http://example.com/a/b/c/test.txt -> test.txt</li>
 * <li>http://example.com/ -> an empty string </li>
 * <li>http://example.com/test.txt?param=value -> test.txt</li>
 * <li>http://example.com/test.txt#anchor -> test.txt</li>
 * </ul>
 * 
 * @param url The input URL
 * @return The URL file name
 */
public static String getFileNameFromUrl(URL url) {

    String urlString = url.getFile();

    return urlString.substring(urlString.lastIndexOf('/') + 1).split("\\?")[0].split("#")[0];
}
Tim Autin
fonte
1
@AlexNauda Substitua url.getFile()por url.toString()e ele trabalha #no caminho.
Sormuras
7
String fileName = url.substring(url.lastIndexOf('/') + 1);
Yogesh Rathi
fonte
7

Existem algumas maneiras:

E / S do arquivo Java 7:

String fileName = Paths.get(strUrl).getFileName().toString();

Apache Commons:

String fileName = FilenameUtils.getName(strUrl);

Usando Jersey:

UriBuilder buildURI = UriBuilder.fromUri(strUrl);
URI uri = buildURI.build();
String fileName = Paths.get(uri.getPath()).getFileName();

Substring:

String fileName = strUrl.substring(strUrl.lastIndexOf('/') + 1);
Giang Phan
fonte
Infelizmente, sua solução Java 7 File I / O não funciona para mim. Eu tenho uma exceção. Tenho sucesso com isso: Paths.get(new URL(strUrl).getFile()).getFileName().toString(); obrigado pela ideia!
Sergey Nemchinov 7/09/19
5

Aqui está a maneira mais simples de fazer isso no Android. Sei que não funcionará em Java, mas pode ajudar o desenvolvedor de aplicativos Android.

import android.webkit.URLUtil;

public String getFileNameFromURL(String url) {
    String fileNameWithExtension = null;
    String fileNameWithoutExtension = null;
    if (URLUtil.isValidUrl(url)) {
        fileNameWithExtension = URLUtil.guessFileName(url, null, null);
        if (fileNameWithExtension != null && !fileNameWithExtension.isEmpty()) {
            String[] f = fileNameWithExtension.split(".");
            if (f != null & f.length > 1) {
                fileNameWithoutExtension = f[0];
            }
        }
    }
    return fileNameWithoutExtension;
}
Bharat Dodeja
fonte
3

Crie um objeto de URL a partir da String. Quando você tem um objeto de URL pela primeira vez, existem métodos para extrair facilmente qualquer trecho de informação que você precisa.

Eu recomendo fortemente o site Javaalmanac, que tem muitos exemplos, mas que mudou desde então. Você pode achar http://exampledepot.8waytrips.com/egs/java.io/File2Uri.html interessante:

// Create a file object
File file = new File("filename");

// Convert the file object to a URL
URL url = null;
try {
    // The file need not exist. It is made into an absolute path
    // by prefixing the current working directory
    url = file.toURL();          // file:/d:/almanac1.4/java.io/filename
} catch (MalformedURLException e) {
}

// Convert the URL to a file object
file = new File(url.getFile());  // d:/almanac1.4/java.io/filename

// Read the file contents using the URL
try {
    // Open an input stream
    InputStream is = url.openStream();

    // Read from is

    is.close();
} catch (IOException e) {
    // Could not open the file
}
Thorbjørn Ravn Andersen
fonte
2

Se você deseja obter apenas o nome do arquivo de um java.net.URL (sem incluir nenhum parâmetro de consulta), você pode usar a seguinte função:

public static String getFilenameFromURL(URL url) {
    return new File(url.getPath().toString()).getName();
}

Por exemplo, este URL de entrada:

"http://example.com/image.png?version=2&amp;modificationDate=1449846324000"

Seria traduzido para esta saída String:

image.png
dokaspar
fonte
2

Descobri que alguns URLs são transmitidos diretamente para FilenameUtils.getNameretornar resultados indesejados e isso precisa ser agrupado para evitar explorações.

Por exemplo,

System.out.println(FilenameUtils.getName("http://www.google.com/.."));

retorna

..

o que duvido que alguém queira permitir.

A função a seguir parece funcionar bem e mostra alguns desses casos de teste e retorna nullquando o nome do arquivo não pode ser determinado.

public static String getFilenameFromUrl(String url)
{
    if (url == null)
        return null;
    
    try
    {
        // Add a protocol if none found
        if (! url.contains("//"))
            url = "http://" + url;

        URL uri = new URL(url);
        String result = FilenameUtils.getName(uri.getPath());

        if (result == null || result.isEmpty())
            return null;

        if (result.contains(".."))
            return null;

        return result;
    }
    catch (MalformedURLException e)
    {
        return null;
    }
}

Isso é finalizado com alguns casos de testes simples no exemplo a seguir:

import java.util.Objects;
import java.net.URL;
import org.apache.commons.io.FilenameUtils;

class Main {

  public static void main(String[] args) {
    validateFilename(null, null);
    validateFilename("", null);
    validateFilename("www.google.com/../me/you?trex=5#sdf", "you");
    validateFilename("www.google.com/../me/you?trex=5 is the num#sdf", "you");
    validateFilename("http://www.google.com/test.png?test", "test.png");
    validateFilename("http://www.google.com", null);
    validateFilename("http://www.google.com#test", null);
    validateFilename("http://www.google.com////", null);
    validateFilename("www.google.com/..", null);
    validateFilename("http://www.google.com/..", null);
    validateFilename("http://www.google.com/test", "test");
    validateFilename("https://www.google.com/../../test.png", "test.png");
    validateFilename("file://www.google.com/test.png", "test.png");
    validateFilename("file://www.google.com/../me/you?trex=5", "you");
    validateFilename("file://www.google.com/../me/you?trex", "you");
  }

  private static void validateFilename(String url, String expectedFilename){
    String actualFilename = getFilenameFromUrl(url);

    System.out.println("");
    System.out.println("url:" + url);
    System.out.println("filename:" + expectedFilename);

    if (! Objects.equals(actualFilename, expectedFilename))
      throw new RuntimeException("Problem, actual=" + actualFilename + " and expected=" + expectedFilename + " are not equal");
  }

  public static String getFilenameFromUrl(String url)
  {
    if (url == null)
      return null;

    try
    {
      // Add a protocol if none found
      if (! url.contains("//"))
        url = "http://" + url;

      URL uri = new URL(url);
      String result = FilenameUtils.getName(uri.getPath());

      if (result == null || result.isEmpty())
        return null;

      if (result.contains(".."))
        return null;

      return result;
    }
    catch (MalformedURLException e)
    {
      return null;
    }
  }
}
Brad Parks
fonte
1

Os URLs podem ter parâmetros no final, isso

 /**
 * Getting file name from url without extension
 * @param url string
 * @return file name
 */
public static String getFileName(String url) {
    String fileName;
    int slashIndex = url.lastIndexOf("/");
    int qIndex = url.lastIndexOf("?");
    if (qIndex > slashIndex) {//if has parameters
        fileName = url.substring(slashIndex + 1, qIndex);
    } else {
        fileName = url.substring(slashIndex + 1);
    }
    if (fileName.contains(".")) {
        fileName = fileName.substring(0, fileName.lastIndexOf("."));
    }

    return fileName;
}
Serhii Bohutskyi
fonte
/pode aparecer em fragmento. Você extrairá as coisas erradas.
Nhahtdh 29/07
1

O Urlobjeto em urllib permite acessar o nome de arquivo sem escape do caminho. aqui estão alguns exemplos:

String raw = "http://www.example.com/some/path/to/a/file.xml";
assertEquals("file.xml", Url.parse(raw).path().filename());

raw = "http://www.example.com/files/r%C3%A9sum%C3%A9.pdf";
assertEquals("résumé.pdf", Url.parse(raw).path().filename());
EricE
fonte
0

resposta de Andy refeito usando split ():

Url u= ...;
String[] pathparts= u.getPath().split("\\/");
String filename= pathparts[pathparts.length-1].split("\\.", 1)[0];
bobince
fonte
0
public String getFileNameWithoutExtension(URL url) {
    String path = url.getPath();

    if (StringUtils.isBlank(path)) {
        return null;
    }
    if (StringUtils.endsWith(path, "/")) {
        //is a directory ..
        return null;
    }

    File file = new File(url.getPath());
    String fileNameWithExt = file.getName();

    int sepPosition = fileNameWithExt.lastIndexOf(".");
    String fileNameWithOutExt = null;
    if (sepPosition >= 0) {
        fileNameWithOutExt = fileNameWithExt.substring(0,sepPosition);
    }else{
        fileNameWithOutExt = fileNameWithExt;
    }

    return fileNameWithOutExt;
}
Campa
fonte
0

Que tal agora:

String filenameWithoutExtension = null;
String fullname = new File(
    new URI("http://www.xyz.com/some/deep/path/to/abc.png").getPath()).getName();

int lastIndexOfDot = fullname.lastIndexOf('.');
filenameWithoutExtension = fullname.substring(0, 
    lastIndexOfDot == -1 ? fullname.length() : lastIndexOfDot);
Leon
fonte
0

Para retornar o nome do arquivo sem extensão e sem parâmetros, use o seguinte:

String filenameWithParams = FilenameUtils.getBaseName(urlStr); // may hold params if http://example.com/a?param=yes
return filenameWithParams.split("\\?")[0]; // removing parameters from url if they exist

Para retornar o nome do arquivo com extensão sem parâmetros, use o seguinte:

/** Parses a URL and extracts the filename from it or returns an empty string (if filename is non existent in the url) <br/>
 * This method will work in win/unix formats, will work with mixed case of slashes (forward and backward) <br/>
 * This method will remove parameters after the extension
 *
 * @param urlStr original url string from which we will extract the filename
 * @return filename from the url if it exists, or an empty string in all other cases */
private String getFileNameFromUrl(String urlStr) {
    String baseName = FilenameUtils.getBaseName(urlStr);
    String extension = FilenameUtils.getExtension(urlStr);

    try {
        extension = extension.split("\\?")[0]; // removing parameters from url if they exist
        return baseName.isEmpty() ? "" : baseName + "." + extension;
    } catch (NullPointerException npe) {
        return "";
    }
}
Chaiavi
fonte
0

Além dos métodos avançados, meu truque simples é StringTokenizer:

import java.util.ArrayList;
import java.util.StringTokenizer;

public class URLName {
    public static void main(String args[]){
        String url = "http://www.example.com/some/path/to/a/file.xml";
        StringTokenizer tokens = new StringTokenizer(url, "/");

        ArrayList<String> parts = new ArrayList<>();

        while(tokens.hasMoreTokens()){
            parts.add(tokens.nextToken());
        }
        String file = parts.get(parts.size() -1);
        int dot = file.indexOf(".");
        String fileName = file.substring(0, dot);
        System.out.println(fileName);
    }
}
Blasanka
fonte
0

Se você estiver usando o Spring , há um auxiliar para lidar com URIs. Aqui está a solução:

List<String> pathSegments = UriComponentsBuilder.fromUriString(url).build().getPathSegments();
String filename = pathSegments.get(pathSegments.size()-1);
Benjamin Caure
fonte
0

retornar novo arquivo (Uri.parse (url) .getPath ()). getName ()

GangrenaGastrit
fonte
-1
create a new file with string image path

    String imagePath;
    File test = new File(imagePath);
    test.getName();
    test.getPath();
    getExtension(test.getName());


    public static String getExtension(String uri) {
            if (uri == null) {
                return null;
            }

            int dot = uri.lastIndexOf(".");
            if (dot >= 0) {
                return uri.substring(dot);
            } else {
                // No extension.
                return "";
            }
        }
Pravin Bhosale
fonte
-1

Eu tenho o mesmo problema, com o seu. Eu resolvi isso com isso:

var URL = window.location.pathname; // Gets page name
var page = URL.substring(URL.lastIndexOf('/') + 1); 
console.info(page)
Via Marie Inte
fonte
Java não é JavaScript
nathanfranke 23/02
-3

importar java.io. *;

import java.net.*;

public class ConvertURLToFileName{


   public static void main(String[] args)throws IOException{
   BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
   System.out.print("Please enter the URL : ");

   String str = in.readLine();


   try{

     URL url = new URL(str);

     System.out.println("File : "+ url.getFile());
     System.out.println("Converting process Successfully");

   }  
   catch (MalformedURLException me){

      System.out.println("Converting process error");

 }

Eu espero que isso te ajude.

Ricardo Felgueiras
fonte
2
O getFile () não faz o que você pensa. De acordo com o documento, na verdade, é getPath () + getQuery, o que é bastante inútil. java.sun.com/j2se/1.4.2/docs/api/java/net/URL.html#getFile ()
bobince