繁体   English   中英

使用Java从100个图像URL的文本文件中提取图像

[英]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.readImageIO.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM