Dapatkan nama file dari URL

146

Di Jawa, diberikan a java.net.URLatau a Stringdalam bentuk http://www.example.com/some/path/to/a/file.xml, apa cara termudah untuk mendapatkan nama file, minus ekstensi? Jadi, dalam contoh ini, saya mencari sesuatu yang kembali "file".

Saya dapat memikirkan beberapa cara untuk melakukan ini, tetapi saya sedang mencari sesuatu yang mudah dibaca dan singkat.

Sietse
sumber
3
ANDA menyadari bahwa tidak ada persyaratan untuk menjadi nama file pada akhirnya, atau bahkan sesuatu yang terlihat seperti nama file. Dalam hal ini, mungkin ada atau tidak ada file.xml di server.
Miserable Variable
2
dalam hal ini, hasilnya adalah string kosong, atau mungkin nol.
Sietse
1
Saya pikir Anda perlu mendefinisikan masalah lebih jelas. Bagaimana dengan akhiran URL berikut? .... / abc, .... / abc /, .... / abc.def, .... / abc.def.ghi, .... / abc? def.ghi
Variabel Menyedihkan
2
Saya pikir itu cukup jelas. Jika URL menunjuk ke suatu file, saya tertarik pada nama file minus ekstensi (jika ada). Bagian kueri berada di luar nama file.
Sietse
4
nama file adalah bagian dari url setelah slash terakhir. ekstensi file adalah bagian dari nama file setelah periode terakhir.
Sietse

Jawaban:

189

Alih-alih menciptakan kembali roda, bagaimana menggunakan 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.
sumber
2
Dalam versi commons-io 2.2 setidaknya Anda masih perlu menangani URL dengan parameter secara manual. Misalnya " example.com/file.xml?date=2010-10-20 "
Luke Quinane
18
FilenameUtils.getName (url) lebih cocok.
ehsun7b
4
Tampaknya aneh untuk menambahkan ketergantungan pada commons-io ketika solusi mudah sudah tersedia hanya menggunakan JDK (lihat URL#getPathdan String#substringatau Path#getFileNameatau File#getName).
Jason C
5
Kelas FilenameUtils dirancang untuk bekerja dengan Windows dan * nix path, bukan URL.
nhahtdh
4
Contoh yang diperbarui untuk menggunakan URL, tunjukkan nilai contoh sampel dan gunakan parameter permintaan.
Nick Grealy
192
String fileName = url.substring( url.lastIndexOf('/')+1, url.length() );

String fileNameWithoutExtn = fileName.substring(0, fileName.lastIndexOf('.'));
Merah asli.
sumber
17
Mengapa downvote? Ini tidak adil. Kode saya berfungsi, saya baru saja memverifikasi kode saya setelah melihat downvote.
Merah asli.
2
Saya membesarkan hati Anda, karena versi ini sedikit lebih mudah dibaca daripada versi saya. Downvote mungkin karena itu tidak berfungsi ketika tidak ada ekstensi atau tidak ada file.
Sietse
1
Anda dapat mengabaikan parameter kedua untuksubstring()
Jon Onstott
12
Ini tidak bekerja untuk keduanya http://example.org/file#anchor, http://example.org/file?p=foo&q=baratauhttp://example.org/file.xml#/p=foo&q=bar
Matthias Ronge
2
Jika Anda membiarkan String url = new URL(original_url).getPath()dan menambahkan kasus khusus untuk nama file yang tidak mengandung .maka ini berfungsi dengan baik.
Jason C
32

Jika Anda tidak perlu menyingkirkan ekstensi file, berikut adalah cara untuk melakukannya tanpa menggunakan manipulasi String yang rentan kesalahan dan tanpa menggunakan pustaka eksternal. Bekerja dengan 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
sumber
1
@Carcigenicate Saya baru saja mengujinya lagi dan sepertinya berfungsi dengan baik. URI.getPath()mengembalikan a String, jadi saya tidak melihat mengapa itu tidak berhasil
Zoltán
1
Nvm. Saya menyadari sekarang bahwa masalah saya adalah bagaimana Clojure menangani var-args selama Java-interop. Kelebihan String tidak berfungsi karena array kosong perlu dilewati juga untuk menangani var-args Paths / get. Ini masih berfungsi meskipun jika Anda menyingkirkan panggilan ke getPath, dan gunakan kelebihan beban URI.
Carcigenicate
@Carcigenicate maksud Anda Paths.get(new URI(url))? Itu sepertinya tidak berhasil bagi saya
Zoltán
getFileName membutuhkan Android api level 26
Manuela
26

Ini harus tentang memotongnya (saya akan menyerahkan penanganan kesalahan kepada Anda):

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
sumber
1
Satu aspek penanganan kesalahan yang perlu Anda pertimbangkan adalah Anda akan berakhir dengan string kosong jika Anda secara tidak sengaja mengirimkannya url yang tidak memiliki nama file (seperti http://www.example.com/atau http://www.example.com/folder/)
rtpHarry
2
Kode tidak berfungsi. lastIndexOftidak bekerja seperti ini. Namun niatnya jelas.
Robert
Diturunkan karena tidak akan berfungsi jika bagian fragmen mengandung garis miring, dan karena ada fungsi khusus yang mencapai ini di apache commons dan di Jawa sejak 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
sumber
13

Satu liner:

new File(uri.getPath).getName

Kode lengkap (dalam 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

Catatan : URI#gePathsudah cukup cerdas untuk menghapus parameter kueri dan skema protokol. Contoh:

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
sumber
1
solusi yang bagus!
CybeX
1
ini adalah pilihan terbaik, karena hanya menggunakan JDK standar
Alexandros
11

Dapatkan Nama File dengan Ekstensi , tanpa Ekstensi , hanya Ekstensi dengan hanya 3 baris:

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

Hasil Log:

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

Semoga ini bisa membantu Anda.

Hiren Patel
sumber
9

Saya datang dengan ini:

String url = "http://www.example.com/some/path/to/a/file.xml";
String file = url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.'));
Sietse
sumber
Atau di URL tanpa file, hanya jalur.
Sietse
kode Anda juga benar. kita tidak seharusnya memeriksa kondisi negatif. upvote untuk Anda. btw apakah nama dirk kuyt terdengar akrab?
Merah asli.
8

Ada beberapa cara:

Java 7 File I / O:

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

Apache Commons:

String fileName = FilenameUtils.getName(strUrl);

Menggunakan 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
sumber
Sayangnya, solusi Java I / O File 7 Anda tidak berfungsi untuk saya. Saya mendapat pengecualian. Saya berhasil dengan ini: Paths.get(new URL(strUrl).getFile()).getFileName().toString(); Terima kasih atas idenya!
Sergey Nemchinov
7

Sederhana saja:

/**
 * 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
sumber
1
@AlexNauda Ganti url.getFile()dengan url.toString()dan berfungsi dengan #di jalan.
Sormuras
7
String fileName = url.substring(url.lastIndexOf('/') + 1);
Yogesh Rathi
sumber
5

Berikut adalah cara paling sederhana untuk melakukannya di Android. Saya tahu ini tidak akan berfungsi di Jawa tetapi mungkin membantu pengembang aplikasi 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
sumber
3

Buat objek URL dari String. Ketika pertama kali Anda memiliki objek URL, ada metode untuk mengeluarkan semua informasi yang Anda butuhkan dengan mudah.

Saya bisa sangat merekomendasikan situs web Javaalmanac yang memiliki banyak contoh, tetapi yang telah dipindahkan. Anda mungkin menemukan http://exampledepot.8waytrips.com/egs/java.io/File2Uri.html menarik:

// 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
sumber
2

Jika Anda hanya ingin mendapatkan nama file dari java.net.URL (tidak termasuk parameter kueri), Anda dapat menggunakan fungsi berikut:

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

Misalnya, URL masukan ini:

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

Akan diterjemahkan ke String keluaran ini:

image.png
dokaspar
sumber
2

Saya telah menemukan bahwa beberapa url ketika disahkan langsung untuk FilenameUtils.getNamemengembalikan hasil yang tidak diinginkan dan ini perlu dibungkus untuk menghindari eksploitasi.

Sebagai contoh,

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

kembali

..

yang saya ragu ada orang yang mau mengizinkan.

Fungsi berikut tampaknya berfungsi dengan baik, dan menunjukkan beberapa kasus uji ini, dan kembali nullketika nama file tidak dapat ditentukan.

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

Ini dibungkus dengan beberapa test case sederhana dalam contoh berikut:

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;
    }
  }
}
Taman Brad
sumber
1

Url dapat memiliki parameter pada akhirnya, ini

 /**
 * 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
sumber
/dapat muncul dalam fragmen. Anda akan mengekstrak hal-hal yang salah.
nhahtdh
1

The Urlobjek di urllib memungkinkan Anda untuk mengakses file unescaped jalan ini. Berikut ini beberapa contohnya:

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
sumber
0

Jawaban andy diulang menggunakan split ():

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

Bagaimana dengan ini:

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
sumber
0

Untuk mengembalikan nama file tanpa ekstensi dan tanpa parameter gunakan yang berikut:

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

Untuk mengembalikan nama file dengan ekstensi tanpa params gunakan ini:

/** 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
sumber
0

Di luar semua metode canggih, trik sederhana saya adalah 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
sumber
0

Jika Anda menggunakan Spring , ada penolong untuk menangani URI. Ini solusinya:

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

kembalikan File baru (Uri.parse (url) .getPath ()). getName ()

GangrenaGastrit
sumber
-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
sumber
-1

Saya memiliki masalah yang sama, dengan masalah Anda. Saya menyelesaikannya dengan ini:

var URL = window.location.pathname; // Gets page name
var page = URL.substring(URL.lastIndexOf('/') + 1); 
console.info(page)
Via Marie Inte
sumber
Java bukan 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");

 }

Saya harap ini akan membantu Anda.

Ricardo Felgueiras
sumber
2
getFile () tidak melakukan apa yang Anda pikirkan. Menurut dokumen itu sebenarnya getPath () + getQuery, yang agak tidak berguna. java.sun.com/j2se/1.4.2/docs/api/java/net/URL.html#getFile ()
bobince