Java - 从 URL 下载具有匹配文件名模式的文件

Java - Download file from URL with matching file name pattern

我想从 URL 下载几个文件。我知道文件名的开头。但下一部分会有所不同。主要是约会。但是对于不同的文件可能会有所不同。从 Java 代码,有没有办法下载具有匹配模式的文件?

如果我在 chrome 中点击下面的 URL,所有文件都会列出,我必须手动下载所需的文件。

http://<ip_address>:<port>/MR/build/report/scan/daily/2021-12-13_120/data/

文件名可以像下面这样。它将具有已知的文件名和日期。日期可以不同。要么与 URL 中的相同,要么与旧版本中的相同。

截至目前,我的 Java 代码如下所示。我必须传递带有确切文件名的完整 URL 才能下载文件。大多数情况下它与 URL 中的日期和数字相同。所以在程序中,我从 URL 中获取日期部分并将其添加到我的文件名中,然后作为 URL 传递。但对于某些文件,它可能会发生变化,对于那些我必须手动下载的文件。

private static void downloadFile(String remoteURLPath, String localPath) {
        System.out.println("DownloadFileTest.downloadFile() Downloading from " + remoteURLPath + "  to = " + localPath);
        FileOutputStream fos = null;
        try {
            URL website = new URL(remoteURLPath);
            ReadableByteChannel rbc = Channels.newChannel(website.openStream());
            fos = new FileOutputStream(localPath);
            fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

参数 remoteURLPath 的传递方式类似于 http://<ip_address>:<port>/MR/build/report/scan/daily/2021-12-13_120/data/scan_report_2021_12_13_120.txt localPathC:\MyDir\MyData\scan_report_2021_12_13_120.txt

一样传递

类似地,其他文件的日期也为 2021_12_13_120。其他文件不会下载。但是会在同一目录中创建空文件,稍后我将删除该文件,因为大小为 0。

有什么方法可以在这里传递模式吗?

喜欢http://<ip_address>:<port>/MR/build/report/scan/daily/2021-12-13_120/data/scan_report_*.txt

有没有办法只传递应该下载文件的目录,而不是传递完整的本地路径,并且名称与远程系统中的名称完全相同?

在 Linux 中,我可以使用 wget 进行模式匹配。但是正在寻找 Java 在所有平台上下载的方法。

wget -r -np -nH --cut-dirs=10 -A "scan_report*.txt" "http://<ip_address>:<port>/MR/build/report/scan/daily/2021-12-13_120/data/"

感谢@FedericoklezCulloca 的评论。我使用 this answer

修改了我的代码

我所做的解决方案是读取所有 html 页面并获取所有 href 值,因为它只有带扩展名的文件名。从那里我有另一个列表,我用它来获取匹配的文件和我下载的文件,然后在问题中使用我的代码。

从URL获取所有href列表的方法。可能可以进行优化。我也没有使用任何额外的库。

private static List<String> getAllHREFListFromURL(String downloadURL) {
    URL url;
    InputStream is = null;
    List<String> hrefListFromURL = new ArrayList<>();
    try {
        url = new URL(downloadURL);

        is = url.openStream();
        byte[] buffer = new byte[1024];
        int bytesRead = -1;
        StringBuilder page = new StringBuilder(1024);
        while ((bytesRead = is.read(buffer)) != -1) {
            String str = new String(buffer, 0, bytesRead);
            page.append(str);
        }

        StringBuilder htmlPage = new StringBuilder(page);
        String search_start = "href=\"";
        String search_end = "\"";
        while (!htmlPage.isEmpty()) {
            int indexOf = htmlPage.indexOf(search_start);
            if (indexOf != -1) {
                String substring = htmlPage.substring(indexOf + search_start.length());
                String linkName = substring.substring(0, substring.indexOf(search_end));
                hrefListFromURL.add(linkName);
                htmlPage = new StringBuilder(substring);
            } else {
                htmlPage = new StringBuilder();
            }
        }
    } catch (MalformedURLException e1) {
        e1.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (Exception e) {
        }
    }
    return hrefListFromURL;
}

获取我需要的文件列表的方法。

private static List<String> getDownloadList(List<String> allHREFListFromURL) {
    List<String> filesList = getMyFilesList();

    List<String> downloadList = new ArrayList<>();
    for (String fileName : filesList) {
        Predicate<String> fileFilter = Pattern.compile(fileName + "*").asPredicate();
        List<String> collect = allHREFListFromURL.stream().filter(fileFilter).collect(Collectors.toList());
        downloadList.addAll(collect);
    }
    return downloadList;
}

private static List<String> getMyFilesList() {
    List<String> filesList = new ArrayList<>();
    filesList.add("scan_report");
    filesList.add("build_report");
    filesList.add("my_reportdata");
    return filesList;
}

downloadList我迭代,用我原来的下载方式下载。