Obtenir le nom du fichier à partir de l'URL

146

En Java, étant donné un java.net.URLou un Stringsous la forme de http://www.example.com/some/path/to/a/file.xml, quel est le moyen le plus simple d'obtenir le nom du fichier, sans l'extension? Donc, dans cet exemple, je recherche quelque chose qui retourne "file".

Je peux penser à plusieurs façons de le faire, mais je recherche quelque chose qui soit facile à lire et court.

Sietse
la source
3
VOUS réalisez qu'il n'est pas nécessaire qu'il y ait un nom de fichier à la fin, ou même quelque chose qui ressemble à un nom de fichier. Dans ce cas, il peut y avoir ou non un fichier.xml sur le serveur.
Miserable Variable
2
dans ce cas, le résultat serait une chaîne vide, ou peut-être null.
Sietse
1
Je pense que vous devez définir le problème plus clairement. Qu'en est-il des terminaisons URLS suivantes? .... / abc, .... / abc /, .... / abc.def, .... / abc.def.ghi, .... / abc? def.ghi
Variable misérable
2
Je pense que c'est assez clair. Si l'URL pointe vers un fichier, je suis intéressé par le nom du fichier moins l'extension (s'il en a une). Les parties de la requête ne font pas partie du nom de fichier.
Sietse
4
le nom du fichier est la partie de l'url après la dernière barre oblique. l'extension de fichier est la partie du nom de fichier après le dernier point.
Sietse

Réponses:

189

Au lieu de réinventer la roue, que diriez-vous d'utiliser 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.
la source
2
Dans la version commons-io 2.2 au moins, vous devez toujours gérer manuellement les URL avec des paramètres. Par exemple, " example.com/file.xml?date=2010-10-20 "
Luke Quinane
18
FilenameUtils.getName (url) est un meilleur ajustement.
ehsun7b
4
Il semble étrange d'ajouter une dépendance à commons-io lorsque des solutions simples sont facilement disponibles en utilisant simplement le JDK (voir URL#getPathet String#substringou Path#getFileNameou File#getName).
Jason C
5
La classe FilenameUtils est conçue pour fonctionner avec Windows et le chemin * nix, pas avec l'URL.
nhahtdh
4
Exemple mis à jour pour utiliser une URL, afficher des exemples de valeurs de sortie et utiliser des paramètres de requête.
Nick Grealy
192
String fileName = url.substring( url.lastIndexOf('/')+1, url.length() );

String fileNameWithoutExtn = fileName.substring(0, fileName.lastIndexOf('.'));
Vraiment rouge.
la source
17
Pourquoi le vote négatif? C'est injuste. Mon code fonctionne, je viens de vérifier mon code après avoir vu le vote négatif.
Vraiment rouge.
2
Je vous ai voté pour, car il est légèrement plus lisible que ma version. Le vote négatif peut être dû au fait qu'il ne fonctionne pas lorsqu'il n'y a pas d'extension ou pas de fichier.
Sietse
1
Vous pouvez laisser le deuxième paramètre àsubstring()
Jon Onstott
12
Cela ne fonctionne pas pour ni http://example.org/file#anchor, http://example.org/file?p=foo&q=barnihttp://example.org/file.xml#/p=foo&q=bar
Matthias Ronge
2
Si vous laissez String url = new URL(original_url).getPath()et ajoutez un cas spécial pour les noms de fichiers qui ne contiennent pas de, .cela fonctionne bien.
Jason C
32

Si vous n'avez pas besoin de vous débarrasser de l'extension de fichier, voici un moyen de le faire sans recourir à une manipulation de String sujette aux erreurs et sans utiliser de bibliothèques externes. Fonctionne avec 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
la source
1
@Carcigenicate Je viens de le tester à nouveau et cela semble fonctionner correctement. URI.getPath()renvoie a String, donc je ne vois pas pourquoi cela ne fonctionnerait pas
Zoltán
1
Nvm. Je réalise maintenant que mon problème était dû à la façon dont Clojure gère les var-args pendant l'interopérabilité Java. La surcharge String ne fonctionnait pas car un tableau vide devait également être passé pour gérer les var-args de Paths / get. Cela fonctionne toujours si vous vous débarrassez de l'appel à getPathet utilisez la surcharge d'URI à la place.
Carcigenicate
@Carcigenicate vous voulez dire Paths.get(new URI(url))? Cela ne semble pas fonctionner pour moi
Zoltán
getFileName nécessite l'api Android niveau 26
Manuela
26

Cela devrait à peu près le couper (je vous laisse la gestion des erreurs):

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
la source
1
Un aspect de la gestion des erreurs que vous devez considérer est que vous vous retrouverez avec une chaîne vide si vous lui transmettez accidentellement une URL qui n'a pas de nom de fichier (tel que http://www.example.com/ou http://www.example.com/folder/)
rtpHarry
2
Le code ne fonctionne pas. lastIndexOfne fonctionne pas de cette façon. Mais l'intention est claire.
Robert
Évalué parce que cela ne fonctionnera pas si la partie fragment contient des barres obliques, et parce qu'il y a des fonctions dédiées qui y parviennent dans apache commons et en Java depuis la 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
la source
13

Bon mot:

new File(uri.getPath).getName

Code complet (dans une 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

Remarque : URI#gePathest déjà suffisamment intelligent pour supprimer les paramètres de requête et le schéma du protocole. Exemples:

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
la source
1
belle solution!
CybeX
1
c'est la meilleure option, car elle n'utilise que le JDK standard
Alexandros
11

Obtenez le nom du fichier avec l'extension , sans extension , uniquement l'extension avec seulement 3 lignes:

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

Résultat du journal:

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

J'espère que cela vous aidera.

Hiren Patel
la source
9

J'ai trouvé ceci:

String url = "http://www.example.com/some/path/to/a/file.xml";
String file = url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.'));
Sietse
la source
Ou sur des URL sans fichier, juste un chemin.
Sietse
votre code est également correct. nous ne sommes de toute façon pas censés vérifier les conditions négatives. un vote positif pour vous. btw le nom dirk kuyt vous semble-t-il familier?
Vraiment rouge.
8

Il existe plusieurs moyens:

E / S de fichier Java 7:

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

Apache Commons:

String fileName = FilenameUtils.getName(strUrl);

Utilisation de Jersey:

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

Sous-chaîne:

String fileName = strUrl.substring(strUrl.lastIndexOf('/') + 1);
Giang Phan
la source
Malheureusement, votre solution d' E / S de fichier Java 7 ne fonctionne pas pour moi. J'ai une exception. Je réussis avec ceci: Paths.get(new URL(strUrl).getFile()).getFileName().toString(); Merci pour l'idée!
Sergey Nemchinov
7

Rester simple :

/**
 * 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
la source
1
@AlexNauda Remplacez url.getFile()par url.toString()et cela fonctionne avec #dans le chemin.
Sormuras
7
String fileName = url.substring(url.lastIndexOf('/') + 1);
Yogesh Rathi
la source
5

Voici le moyen le plus simple de le faire sous Android. Je sais que cela ne fonctionnera pas en Java, mais cela peut aider les développeurs d'applications 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
la source
3

Créez un objet URL à partir de la chaîne. Lorsque vous avez un objet URL pour la première fois, il existe des méthodes pour extraire facilement n'importe quel extrait d'informations dont vous avez besoin.

Je peux fortement recommander le site Web Javaalmanac qui a des tonnes d'exemples, mais qui a depuis déménagé. Vous pourriez trouver http://exampledepot.8waytrips.com/egs/java.io/File2Uri.html intéressant:

// 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
la source
2

Si vous souhaitez obtenir uniquement le nom de fichier à partir d'un java.net.URL (sans aucun paramètre de requête), vous pouvez utiliser la fonction suivante:

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

Par exemple, cette URL d'entrée:

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

Serait traduit en cette chaîne de sortie:

image.png
Dokaspar
la source
2

J'ai constaté que certaines URL transmises directement à FilenameUtils.getName renvoyer des résultats indésirables, cela doit être encapsulé pour éviter les exploits.

Par exemple,

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

Retour

..

ce que je doute que quiconque veuille autoriser.

La fonction suivante semble fonctionner correctement et montre certains de ces cas de test, et elle retourne nulllorsque le nom de fichier ne peut pas être déterminé.

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

Ceci est résumé avec quelques cas de tests simples dans l'exemple suivant:

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
la source
1

Les URL peuvent avoir des paramètres à la fin, ceci

 /**
 * 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
la source
/peut apparaître en fragments. Vous extrairez les mauvaises choses.
nhahtdh le
1

L' Urlobjet dans urllib vous permet d'accéder au nom de fichier sans échappement du chemin. Voici quelques exemples:

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
la source
0

réponse d'Andy refaite en utilisant split ():

Url u= ...;
String[] pathparts= u.getPath().split("\\/");
String filename= pathparts[pathparts.length-1].split("\\.", 1)[0];
bobince
la source
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
la source
0

Que dis-tu de ça:

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);
Léon
la source
0

Pour renvoyer le nom de fichier sans extension et sans paramètres, utilisez ce qui suit:

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

Afin de renvoyer le nom de fichier avec l'extension sans paramètres, utilisez ceci:

/** 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
la source
0

Au-delà de toutes les méthodes avancées, mon truc simple est 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
la source
0

Si vous utilisez Spring , il existe un assistant pour gérer les URI. Voici la solution:

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

renvoie un nouveau fichier (Uri.parse (url) .getPath ()). getName ()

GangrenaGastrit
la source
-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
la source
-1

J'ai le même problème, avec le vôtre. Je l'ai résolu par ceci:

var URL = window.location.pathname; // Gets page name
var page = URL.substring(URL.lastIndexOf('/') + 1); 
console.info(page)
Via Marie Inte
la source
Java n'est pas JavaScript
nathanfranke
-3

import 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");

 }

J'espère que cela t'aidera.

Ricardo Felgueiras
la source
2
getFile () ne fait pas ce que vous pensez. Selon la documentation, il s'agit en fait de getPath () + getQuery, ce qui est plutôt inutile. java.sun.com/j2se/1.4.2/docs/api/java/net/URL.html#getFile ()
bobince