0

I am using and evaluating two ways (but if something other is better tell me):

(1) Using ImageIO:

URL url = new URL(photoUrl);    
BufferedImage image = ImageIO.read(url);
ImageIO.write(image, "jpg", new File(absoluteDestination + photoId + ".jpg"));

(2) Using FileOutputStream

URL url = new URL(photoUrl);    
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(absoluteDestination + photoId + ".jpg");

byte[] b = new byte[2048];
int length;

while ((length = is.read(b)) != -1) {
    os.write(b, 0, length);
}
is.close();
os.close();

(1) Seems to me smarter and faster (about 10x faster, maybe it demands something to another process because I think that 45ms to download a 46KB image are not enough). But opens a icon in the dock (I'm using a Mac) and this disturbs me a bit

(2) Seems a bit "ugly in the form" and lower, but it doesn't open the icon.

Which is the best for you? Is there a new and old way to do? Do you think there's a better way? Thanks

EDIT:

I have made new tests about the speed of the two methods. Measuring the time of execution of (1) and (2) starting from the line before the first line (of the code written in the example here). The speed of (1) wa 10x faster than (2). BUT measuring the time from the beginning of the code (first line of the .java) the (2) is 30% faster than (1).

I suppose that the (1) delegates the real download to another process (maybe this is the "app" which pops up in the dock).

fabio_vac
  • 584
  • 1
  • 6
  • 14
  • I'm surprised to see anything custom for images to be so much faster than just a raw stream. I'm not familiar with ImageIO, but I guess it has to make some additional work. Did you try increasing buffer size in solution 2 ? – TMG Nov 29 '15 at 17:13
  • Have you tried the accepted anwser here: http://stackoverflow.com/a/4697271/4358405 – TMG Nov 29 '15 at 17:15
  • I'm surprised that the first version would be faster, considering it's decoding and reencoding the image. – Kayaman Nov 29 '15 at 17:15
  • 1
    For a standard library solution, I'd go with [Files.copy](http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html). – Kayaman Nov 29 '15 at 17:17
  • It is impossible that (1) is faster. How did you test it? Did you use the same image for (2) and (2)? Did you eliminate the effects of caching? – user207421 Nov 29 '15 at 18:54

1 Answers1

0

Thanks to @kayaman I have tried the Files.copy method, and this is the best I have used because of: speed, elegance, compactness of code:

(3) Using Files.copy()

try (InputStream in = new URL(photoUrl).openStream()) {
    Files.copy(in, Paths.get(absoluteDestination + photoId + ".jpg"), StandardCopyOption.REPLACE_EXISTING);
}

The StandardCopyOption.REPLACE_EXISTING is optional an used if you want to replace the file (if the file exists).

fabio_vac
  • 584
  • 1
  • 6
  • 14
  • There's no speed difference between this and your original (2), except whatever is caused by the buffer size, which I would increase to at least 8192 bytes. – user207421 Nov 30 '15 at 11:18
  • @EJP Yes but I think (3) is far more elegant than the (2). Less code and more compact! What do you think? – fabio_vac Nov 30 '15 at 11:53