41

URL から ePub ファイルをダウンロードしています。

ユーザーが同じファイルを再ダウンロードしようとすると、警告/エラーメッセージが表示され、そのファイルが再度ダウンロードされないようにするメカニズムを実装したいと考えています。

これを実装するには、ライブラリに存在するファイルの名前と、ユーザーがダウンロードしようとしているファイルの名前を確認する必要があります。

しかし、ファイル名ではなく、このダウンロードリンクしかありません。

既存のファイルと比較するために、ダウンロードする前にファイルの名前を取得する方法は?

4

6 に答える 6

101

Android では、guessFileName() メソッドを使用できます。

URLUtil.guessFileName(url, null, null)

あるいは、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"

ソースコード全体はこちらにあります: https://ideone.com/uFWxTL

于 2012-07-20T08:52:41.730 に答える
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];
}
于 2014-11-07T21:46:45.640 に答える
3

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()を参照してください。

于 2016-05-13T15:42:59.067 に答える
2

ファイル名を比較する必要はありません。絶対パスでファイルの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
    }
}
于 2012-10-02T08:48:32.047 に答える