gpt4 book ai didi

java - 如何使用 Java 套接字 HTTP/1.1 请求下载图像?

转载 作者:可可西里 更新时间:2023-11-01 17:07:47 25 4
gpt4 key购买 nike

我正在尝试使用 java.net.Socket 下载图像,而不使用 java.net.URL 和外部库。这是我所拥有的,但我不确定是什么不起作用。

        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());

为了查看流中的内容,将 BufferedImage 行替换为:

    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null && inputLine.trim() != "0") {
System.out.println(inputLine);
}

大概 ImageIO.read(...) 方法不期望套接字输入流中的 HTTP header 。但我不确定如何删除标题。我试过使用 BufferedReader 读取标题行,然后将套接字输入流传递给 ImageIO.read(...) 但这没有用。

这是 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

����...

末尾的不可打印字符似乎表明标题后面是某种图像。但是我怎样才能把它变成 java.awt.image.BufferedImagejavafx.scene.image.Image?后者有一个接受输入流的构造函数,我试过了,但它不起作用(因为 http header ?)。这个问题类似于this一个,但我正在尝试创建图像而不是文件。

最佳答案

使用 BufferedReader 是错误的,原因有两个:

  1. 它将字节转换为 String,然后您将其转换回字节以将其发送到输出流。转换可能(并且很可能会)导致数据丢失;
  2. 它解析的字节太多,您无法控制它。

您需要通过外科手术来解决这个问题,创建一个所需大小的字节缓冲区,并使用 InputStream 按照您自己的方式逐字节读取流。此外,由于您知道 HTTP header 结尾是“\r\n\r\n”(或 13 10 13 10 字节),您可以扫描自己的缓冲区以查找此模式并采取相应措施。

最好的办法是将图像下载到文件中,然后使用 ImageIO 从本地文件中读取它。

这是允许您通过删除标题来下载图像文件(或任何其他文件)的代码:

    // Initialize the streams.
final FileOutputStream fileOutputStream = new FileOutputStream(file);
final InputStream inputStream = socket.getInputStream();

// Header end flag.
boolean headerEnded = false;

byte[] bytes = new byte[2048];
int length;
while ((length = inputStream.read(bytes)) != -1) {
// If the end of the header had already been reached, write the bytes to the file as normal.
if (headerEnded)
fileOutputStream.write(bytes, 0, length);

// This locates the end of the header by comparing the current byte as well as the next 3 bytes
// with the HTTP header end "\r\n\r\n" (which in integer representation would be 13 10 13 10).
// If the end of the header is reached, the flag is set to true and the remaining data in the
// currently buffered byte array is written into the file.
else {
for (int i = 0; i < 2045; i++) {
if (bytes[i] == 13 && bytes[i + 1] == 10 && bytes[i + 2] == 13 && bytes[i + 3] == 10) {
headerEnded = true;
fileOutputStream.write(bytes, i+4 , 2048-i-4);
break;
}
}
}
}
inputStream.close();
fileOutputStream.close();

关于java - 如何使用 Java 套接字 HTTP/1.1 请求下载图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33576510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com