I am trying to download images using java.net.Socket
without java.net.URL
and external libraries. Here is what I have and I am not sure what isn't working.
String domain = "www.manchester.edu";
String path = "/images/default-source/default-album/slide1.jpg";
Socket socket = new Socket(domain,80);
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
out.println("" +
"Get "+path+" HTTP/1.1\n" +
"Host: "+domain+"\n"+
"");
out.println();
out.flush();
BufferedImage image = ImageIO.read(socket.getInputStream());
In order to see what is coming through the stream, exchange the BufferedImage
line for:
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null && inputLine.trim() != "0") {
System.out.println(inputLine);
}
Presumably the ImageIO.read(...)
method does not expect the HTTP header in the socket input stream. But I am not sure how to remove the header. I've tried reading the header lines with BufferedReader
and then passing the socket input stream to ImageIO.read(...)
but that did not work.
Here is the string printed by BufferedReader
:
HTTP/1.1 200 OK
Cache-Control: public, max-age=7776000
Content-Length: 96876
Content-Type: image/jpeg
Expires: Thu, 04 Feb 2016 21:36:46 GMT
Last-Modified: Tue, 15 Sep 2015 14:23:40 GMT
Server: Microsoft-IIS/8.5
content-disposition: inline; filename=slide1.jpg
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 06 Nov 2015 21:36:46 GMT
����...
The non-printable characters at the end seems to indicate that what follows the header is an image of some sort. But how can I turn this into a java.awt.image.BufferedImage
or a javafx.scene.image.Image
? The latter has a constructor that takes an input stream, and I've tried that, but it doesn't work (because of the http header?). This question is similar to this one, but I am trying to create an image not a file.
Using
BufferedReader
is a mistake for 2 reasons:String
which you then convert back into bytes to send it into the output stream. The conversions may (and probably will) lead to loss of data;You need to approach this surgically, creating a buffer of bytes of the size you want and using an
InputStream
to read the stream byte-by-byte on your own terms. Also, since you know that the HTTP header ending is "\r\n\r\n" (or 13 10 13 10 in bytes), you can scan your own buffer for this pattern and act accordingly.Your best bet is to download the image to a file and then use the ImageIO to read it from the local file.
Here's the code that will allow you to download an Image file (or any other file) by cutting out the header: