我有一个包含大量图片网址的文字文件。我需要获取一个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();
}
}
答案 0 :(得分:2)
您可以利用预先存在的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
。< / p>
接下来,我们需要从文本文件中读取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
是一个阻塞调用,这意味着在所有任务完成或失败之前,它不会返回。方便。
您可以选择处理生成的List
Future
个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();
}
}
的返回结果
@Scripts.Render("~/Scripts/Owner.js")
在此示例中,它正在处理列表以查找失败的任务。
有关详细信息,请查看Reading/Loading an Image,Writing/Saving an Image,Executors和Reading, Writing, and Creating Files
答案 1 :(得分:0)
答案 2 :(得分:0)
要从网址文字中获取图片,您可以使用以下代码:
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);
}
}
}