Android 在下载文件之前从 URL 解析文件名

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11575943/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:06:06  来源:igfitidea点击:

Parse file name from URL before downloading the file

androiddownload

提问by GAMA

I'm downloading an ePub file from a URL.

我正在从 URL 下载 ePub 文件。

Now I want to implement a mechanism by which if user tries to re-download the same file, he should get warning/error message and that file should not bedownloaded again.

现在我想实现一种机制,如果用户尝试重新下载同一个文件,他应该收到警告/错误消息,并且不应再次下载该文件。

To implement this, I need to check the name of the file present in my library with the name of the file user is trying to download.

为了实现这一点,我需要使用用户尝试下载的文件名检查我的库中存在的文件名。

But I just have this download link, and not the file name.

但我只有这个下载链接,而不是文件名。

How to get the name of the file before download in order to compare it with the existing file?

如何在下载前获取文件名以便与现有文件进行比较?

回答by Caner

In android you can use the guessFileName() method:

在 android 中,您可以使用guessFileName() 方法

URLUtil.guessFileName(url, null, null)

Alternatively, a simplistic solutionin Java could be:

或者,Java 中的一个简单解决方案可能是:

String fileName = url.substring(url.lastIndexOf('/') + 1);

(Assuming your url is in the format: http://xxxxxxxxxxxxx/filename.ext)

(假设你的URL的格式为:http://xxxxxxxxxxxxx/filename.ext

UPDATE March 23, 2018

2018 年 3 月 23 日更新

This question is getting lots of hits and someone commented my 'simple' solution does not work with certain urls so I felt the need to improve the answer.

这个问题得到了很多点击,有人评论说我的“简单”解决方案不适用于某些网址,所以我觉得有必要改进答案。

In case you want to handle more complex url pattern, I provided a sample solution below. It gets pretty complex quite quickly and I'm pretty sure there are some odd cases my solution still can't handle but nevertheless here it goes:

如果您想处理更复杂的 url 模式,我在下面提供了一个示例解决方案。它很快变得非常复杂,我很确定我的解决方案仍然无法处理一些奇怪的情况,但仍然如此:

public static String getFileNameFromURL(String url) {
    if (url == null) {
        return "";
    }
    try {
        URL resource = new URL(url);
        String host = resource.getHost();
        if (host.length() > 0 && url.endsWith(host)) {
            // handle ...example.com
            return "";
        }
    }
    catch(MalformedURLException e) {
        return "";  
    }

    int startIndex = url.lastIndexOf('/') + 1;
    int length = url.length();

    // find end index for ?
    int lastQMPos = url.lastIndexOf('?');
    if (lastQMPos == -1) {
        lastQMPos = length; 
    }

    // find end index for #
    int lastHashPos = url.lastIndexOf('#');
    if (lastHashPos == -1) {
        lastHashPos = length;   
    }

    // calculate the end index
    int endIndex = Math.min(lastQMPos, lastHashPos);
    return url.substring(startIndex, endIndex);
}

This method can handle these type of input:

此方法可以处理以下类型的输入:

Input: "null" Output: ""
Input: "" Output: ""
Input: "file:///home/user/test.html" Output: "test.html"
Input: "file:///home/user/test.html?id=902" Output: "test.html"
Input: "file:///home/user/test.html#footer" Output: "test.html"
Input: "http://example.com" Output: ""
Input: "http://www.example.com" Output: ""
Input: "http://www.example.txt" Output: ""
Input: "http://example.com/" Output: ""
Input: "http://example.com/a/b/c/test.html" Output: "test.html"
Input: "http://example.com/a/b/c/test.html?param=value" Output: "test.html"
Input: "http://example.com/a/b/c/test.html#anchor" Output: "test.html"
Input: "http://example.com/a/b/c/test.html#anchor?param=value" Output: "test.html"

You can find the whole source code here: https://ideone.com/uFWxTL

你可以在这里找到完整的源代码:https: //ideone.com/uFWxTL

回答by sealskej

Try to use URLUtil.guessFileName(url, null, null)for example. I think this is the best Android way.

URLUtil.guessFileName(url, null, null)例如尝试使用。我认为这是最好的Android方式。

More info here: https://developer.android.com/reference/android/webkit/URLUtil.html#guessFileName(java.lang.String, java.lang.String, java.lang.String)

更多信息:https: //developer.android.com/reference/android/webkit/URLUtil.html#guessFileName(java.lang.String, java.lang.String, java.lang.String)

回答by Tim Autin

Keep it 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];
}

回答by Himanshu Shekhar

I think using URL#getPath() should simplify things.

我认为使用 URL#getPath() 应该可以简化事情。

public static String getFileNameFromUrl(URL url) {

    String urlPath = url.getPath();

    return urlPath.substring(urlPath.lastIndexOf('/') + 1);
}

See, http://developer.android.com/reference/java/net/URL.html#getPath()

见,http://developer.android.com/reference/java/net/URL.html#getPath()

回答by Shiv

You dont really have to compare file names. Just make Fileobject for the file with absolute path and check if file exists.

你真的不必比较文件名。只需为具有绝对路径的文件创建File对象并检查文件是否存在。

protected boolean need2Download(String fileName) {

    File basePath = new File(BOOK_STORE_PATH);

    File fullPath = new File(basePath, fileName);

    if (fullPath.exists())
        return false;
    return true;
}

protected void downloadFile(String url) {
    String fileName = url.substring(url.lastIndexOf('/') + 1);

    if (need2Download(fileName)) {
        // download
    }
}

回答by Naveen Kumar M

Get file name from FilenameUtilsfrom apache commons-io

从获得的文件名FilenameUtilsapache commons-io

URL url = URL(fileUrl)
String fileName = FilenameUtils.getName(url.getPath())

To this add commons-iodependency in build.gradle(app)

为此commons-io在 build.gradle(app) 中添加依赖项

implementation "commons-io:commons-io:2.6"

It also extracts the file name from the complex URL like below

它还从复杂的 URL 中提取文件名,如下所示

http://www.example.com/some/path/to/a/file.xml?foo=bar#test

http://www.example.com/some/path/to/a/file.xml?foo=bar#test