[英]Extracting images from a text file of 100 image urls using java
我有一个文本文件,其中逐行包含很多图像网址。 我需要获得一个Java代码,用于自动提取这些图像并将这些图像保存到文件中。 我知道如何从单个URL保存图像,但是如何修改代码以进行多线程处理? 我想使用原始文件名将所有图像保存在一个文件夹下。 我试图用谷歌搜索出许多代码,但是一切都失败了。 请帮助我找到解决方案。 答案将不胜感激。
我用来保存单个图像的代码是:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
public class SaveImageFromUrl {
public static void main(String[] args) throws Exception {
String imageUrl = "http://http://img.emol.com/2015/04/25/nepalterremoto02ok_2260.jpg";
String destinationFile = "/home/abc/image.jpg";
saveImage(imageUrl, destinationFile);
}
public static void saveImage(String imageUrl, String destinationFile) throws IOException {
URL url = new URL(imageUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
}
}
您可以利用预先存在的API ...
Files.readAllLines
读取文件 ImageIO.read
和ImageIO.write
下载文件 Executor
API可运行并发任务以使其更快 因此,基本上,从每个URL下载图像是相同的过程,可以将其封装为一个简单的任务。
public class DownloadImageFromURLTask implements Callable<File> {
private URL url;
private String path;
public DownloadImageFromURLTask(URL url, String path) {
this.url = url;
this.path = path;
}
@Override
public File call() throws Exception {
BufferedImage img = ImageIO.read(url);
String name = url.getPath();
name = name.substring(name.lastIndexOf("/"));
File output = new File(path, name);
ImageIO.write(img, "jpg", output);
return output;
}
}
我用Callable
在这里,因为这将插件安装到Executor
API,让我得到返回的结果,这是File
在图像被下载。
因此,接下来,我们需要从文本文件中读取URL并构建要执行的任务列表...
List<String> listOfURLs = Files.readAllLines(new File("ListOfURLs.txt").toPath());
List<DownloadImageFromURLTask> listOfTasks = new ArrayList<>(listOfURLs.size());
String path = "/home/abc";
for (String url : listOfURLs) {
listOfTasks.add(new DownloadImageFromURLTask(new URL(url), path));
}
为了简单起见,我只使用了Files.readAllLines
接下来,我们需要执行所有任务...
ExecutorService exector = Executors.newFixedThreadPool(4);
List<Future<File>> listOfFutures = exector.invokeAll(listOfTasks);
这是使用固定大小的线程池,这允许我们进行一些性能调整,因为每个任务都会被池化,直到有一个线程可以运行它为止。
在这里使用invokeAll
是一个阻塞调用,这意味着在所有任务完成或失败之前,它不会返回。 方便。
(可选)您可以处理Future
的结果List
,这些结果带有Callable
的返回结果。
for (int index = 0; index < listOfFutures.size(); index++) {
Future<File> future = listOfFutures.get(index);
try {
File file = future.get();
} catch (ExecutionException ex) {
String url = listOfURLs.get(index);
System.out.println("Failed to download image from " + url);
ex.printStackTrace();
}
}
在此示例中,它正在处理列表以查找失败的任务。
有关更多详细信息,请参阅读取/加载图像 , 写入/保存图像 , 执行程序以及读取,写入和创建文件 。
您可以在命令行上使用curl来获取多个文件。 但是,我假设您正在尝试学习Java并发性,所以我使用并发性重编程了您的程序:
更新:现在将处理文件并下载每个URL,并保留原始文件名
/**
* Created by justin on 6/20/15.
*/
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.System;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.io.File;
import java.nio.file.Files;
class ImageSaver implements Runnable {
private final String imageUrl;
private final String destinationFile;
private Exception exception;
public ImageSaver(String imageUrl, String destinationFile) {
this.imageUrl = imageUrl;
this.destinationFile = destinationFile;
this.exception = null;
}
public boolean isFail() {
return exception != null;
}
public String toString() {
return this.imageUrl + " -> " + this.destinationFile + " Error: " + exception.toString();
}
@Override
public void run() {
try {
URL url = null;
url = new URL(imageUrl);
System.out.println("Getting " + imageUrl);
url.openConnection();
InputStream is = url.openStream();
System.out.println("Opening " + imageUrl);
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
System.out.println("Finished getting " + imageUrl);
} catch (Exception e) {
exception = e;
}
}
}
public class SaveImageFromUrl {
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.out.println("Usage: <file with urls on each line> <dest path>");
return;
}
String destPath = args[1];
List<String> listOfURLs = Files.readAllLines(new File(args[0]).toPath());
ExecutorService executor = Executors.newFixedThreadPool(5);
List<ImageSaver> save = new ArrayList<ImageSaver>();
for (String path : listOfURLs) {
String fn = new File(path).getName();
ImageSaver worker = new ImageSaver(path, destPath + fn);
save.add(worker);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
Thread.yield();
}
for (ImageSaver s : save) {
if (s.isFail()) {
System.out.println("Failed to download " + s);
}
}
executor.shutdown();
System.out.println("All Done");
}
}
要从网址文本获取图片,您可以使用以下代码:
public class SaveImageFromUrl {
BufferedImage img = null;
public static void main(String[] args) {
String path = "https://upload.wikimedia.org/wikipedia/commons/1/1e/Stonehenge.jpg";
String destinationFile = "C:\\Users\\user\\Desktop";
try {
BufferedImage tmp = ImageIO.read(new URL(path));
ImageIO.write(tmp, "jpg", new File(destinationFile + "\\" + "image" + ".jpg"));
} catch (Exception ex) {
System.out.println("Exception ex ///" + ex);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.