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

Android 在下载文件之前从URL解析文件名,android,download,Android,Download,我正在从URL下载一个ePub文件 现在我想实现一种机制,如果用户试图重新下载同一个文件,他将收到警告/错误消息,并且不应再次下载该文件 为了实现这一点,我需要检查我的库中存在的文件名和用户试图下载的文件名 但我只知道,而不是文件名 如何在下载前获取文件名,以便与现有文件进行比较?在android中,您可以使用: 或者,Java中的简化解决方案可以是: String fileName = url.substring(url.lastIndexOf('/') + 1); 假设您的url采用以下格

我正在从URL下载一个ePub文件

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

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

但我只知道,而不是文件名

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

在android中,您可以使用:

或者,Java中的简化解决方案可以是:

String fileName = url.substring(url.lastIndexOf('/') + 1);
假设您的url采用以下格式:http://xxxxxxxxxxxxx/filename.ext

更新日期:2018年3月23日

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

若您想处理更复杂的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);
}
此方法可以处理以下类型的输入:

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"

您可以在这里找到完整的源代码:

您实际上不必比较文件名。只需将文件对象设置为具有绝对路径的文件,并检查文件是否存在

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
    }
}
例如,尝试使用URLUtil.guessFileNameurl、null、null。我认为这是最好的安卓方式

更多信息请点击此处:

保持简单:

/**
 * 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];
}

我认为使用URLgetPath应该可以简化事情

public static String getFileNameFromUrl(URL url) {

    String urlPath = url.getPath();

    return urlPath.substring(urlPath.lastIndexOf('/') + 1);
}
请参阅,

从文件名获取文件名从apache commons io获取文件名

为此,在build.gradleapp中添加commons io依赖项

implementation "commons-io:commons-io:2.6"
它还从复杂的URL中提取文件名,如下所示


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

假设我有一个链接,其中包含书店收藏,例如www.bookstore.com,我从中选择一本URL为www.bookstore.com/book1.epub的书,该书应下载到我的图书馆。如何获取特定书籍的URL,即www.bookstore.com/book1.epub???webView.getUrl除了第一次加载外,根本不会被解雇。只有在没有params?param=value或anchor-anchor的情况下,您的解决方案才有效。非常感谢您的回答,它有助于洛蒂使用它,但不是因为简化了事情,使用getPath,您可以处理具有如下查询参数的urlhttt://domain.com/file.ext?a=1anchor 和@TimAutin一样,但对我来说更具可读性。欢迎来到堆栈溢出!只有代码的答案没有特别的帮助。请添加一些关于此代码如何解决问题的描述。
URL url = URL(fileUrl)
String fileName = FilenameUtils.getName(url.getPath())
implementation "commons-io:commons-io:2.6"
 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);
}