我正在从网址下载ePub文件。
现在我想实现一种机制,如果用户尝试重新下载同一个文件,他应该收到警告/错误消息,而文件不应该再次下载。
为了实现这一点,我需要检查我的库中存在的文件的名称,以及用户试图下载的文件的名称。
但我只有this download link,而不是文件名。
如何在下载之前获取文件名,以便将其与现有文件进行比较?
答案 0 :(得分:71)
在Android中,您可以使用the guessFileName() method:
URLUtil.guessFileName(url, null, null)
或者,Java中的 简单化解决方案 可以是:
String fileName = url.substring(url.lastIndexOf('/') + 1);
(假设您的网址格式为:http://xxxxxxxxxxxxx/filename.ext
)
更新2018年3月23日
这个问题得到了很多点击,有人评论说我的“简单”解决方案不适用于某些网址,所以我觉得有必要改进答案。
如果您想处理更复杂的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"
您可以在此处找到完整的源代码:https://ideone.com/uFWxTL
答案 1 :(得分:42)
尝试使用URLUtil.guessFileName(url, null, null)
作为示例。我认为这是最好的Android方式。
答案 2 :(得分:8)
保持简单:
/**
* 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];
}
答案 3 :(得分:2)
你真的不必比较文件名。只需为具有绝对路径的文件创建文件对象,并检查文件是否存在。
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
}
}
答案 4 :(得分:1)
我认为使用URL#getPath()可以简化事情。
public static String getFileNameFromUrl(URL url) {
String urlPath = url.getPath();
return urlPath.substring(urlPath.lastIndexOf('/') + 1);
}
请参阅http://developer.android.com/reference/java/net/URL.html#getPath()
答案 5 :(得分:0)
从FilenameUtils
的{{1}}获取文件名
apache commons-io
为此在build.gradle(app)中添加URL url = URL(fileUrl)
String fileName = FilenameUtils.getName(url.getPath())
依赖项
commons-io
它也从复杂的URL中提取文件名,如下所示
implementation "commons-io:commons-io:2.6"
答案 6 :(得分:0)
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);
}