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 中的相同,要么与旧版本中的相同。
- scan_report_2021_12_13_120.txt
- build_report_2021_12_10_110.txt
- my_reportdata_2021_11_30_110.txt
截至目前,我的 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
localPath
像 C:\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
我迭代,用我原来的下载方式下载。
我想从 URL 下载几个文件。我知道文件名的开头。但下一部分会有所不同。主要是约会。但是对于不同的文件可能会有所不同。从 Java 代码,有没有办法下载具有匹配模式的文件?
如果我在 chrome 中点击下面的 URL,所有文件都会列出,我必须手动下载所需的文件。
http://<ip_address>:<port>/MR/build/report/scan/daily/2021-12-13_120/data/
文件名可以像下面这样。它将具有已知的文件名和日期。日期可以不同。要么与 URL 中的相同,要么与旧版本中的相同。
- scan_report_2021_12_13_120.txt
- build_report_2021_12_10_110.txt
- my_reportdata_2021_11_30_110.txt
截至目前,我的 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
localPath
像 C:\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
我迭代,用我原来的下载方式下载。