簡體   English   中英

Java從重定向的“友好”網址獲取下載文件名

[英]Java get filename of download from redirected 'friendly' url

我正在嘗試從給定的 URL 下載文件,該 URL 可能是也可能不是該文件的直接鏈接。 有誰知道如果 URL 是間接鏈接(即http://www.example.com/download.php?getFile=1 ),我如何檢測要寫入的文件名? 如果 URL 是從 URL 中提取文件名的直接鏈接並開始寫入提取的文件名,則沒有問題,但使用重定向鏈接,到目前為止我發現的唯一方法是寫入任意文件名 - foo.txt -然后嘗試使用它。 問題是我真的需要文件名(和擴展名)是正確的。 我正在使用的代碼示例是:(“else”子句中的部分既未完成也未工作):

public static boolean dlFile(String URL, String dest){
    try{
        URL grab = new URL(URL);
        ReadableByteChannel rbc = Channels.newChannel(grab.openStream());
        String fnRE = ".*/([a-zA-Z0-9\\-\\._]+)$";
            Pattern pattern = Pattern.compile(fnRE);
        Matcher matcher = pattern.matcher(URL);
        String fName = "";
        if(matcher.find()) fName = matcher.group(1);
        else { //filename cannot be extracted - do something here - below doesn't work raises MalformedURLExcpetion
            URL foo = new URL(URL);
            HttpURLConnection fooConnection = (HttpURLConnection) foo.openConnection();
            URL secondFoo = new URL(fooConnection.getHeaderField("Location"));
            System.out.println("Redirect URL: "+secondFoo);
            fooConnection.setInstanceFollowRedirects(false);
            URLConnection fooURL = secondFoo.openConnection();
        }
        System.out.println("Connection to "+URL+" established!");
        if(dest.endsWith("/")){}
        else dest+="/";
        System.out.println("Writing "+fName+" to "+dest);
        FileOutputStream fos = new FileOutputStream(dest+fName);
        fos.getChannel().transferFrom(rbc, 0, 1 << 24);

我相信一定有一種簡單的方法可以從標題或類似的東西中獲取文件名,但我不知道如何獲取它。 提前致謝,

假設響應具有“位置”標頭字段,我能夠獲得指向包含多個重定向的 url 的直接鏈接,如下所示:

String location = "http://www.example.com/download.php?getFile=1";
HttpURLConnection connection = null;
for (;;) {
    URL url = new URL(location);
    connection = (HttpURLConnection) url.openConnection();
    connection.setInstanceFollowRedirects(false);
    String redirectLocation = connection.getHeaderField("Location");
    if (redirectLocation == null) break;
    location = redirectLocation;
}
//and finally:
String fileName = location.substring(location.lastIndexOf('/') + 1, location.length());

我認為最好使用 Java Jsoup庫,然后使用以下方法:

public static void downloadFileJsoup(String URL, String PATH) throws IOException {
    Response res = Jsoup.connect(URL)
            .userAgent("Mozilla")
            .timeout(30000)
            .followRedirects(true)
            .ignoreContentType(true)
            .maxBodySize(20000000)//Increase value if download is more than 20MB
            .execute(); 
    String remoteFilename=res.header("Content-Disposition").replaceFirst("(?i)^.*filename=\"?([^\"]+)\"?.*$", "$1");
    String filename = PATH + remoteFilename;
    FileOutputStream out = (new FileOutputStream(new java.io.File(filename)));
    out.write( res.bodyAsBytes());
    out.close();
}

不,一般沒辦法。 響應通常不包含該信息,因為您沒有向數據流添加任何自己的協議信息(以防您可以控制服務器)。

無論如何,您要求提供文件擴展名。 也許使用正確的內容類型你就完成了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM