本文最后更新于2019年9月14日,已超过 1 年没有更新,如果文章内容失效,还请反馈给我,谢谢!
=Start=
缘由:
本文主要是对之前记录的「Java中如何发起HTTP请求」一文的补充/修正,当时只考虑了用Java发起GET/POST请求,然后读取返回的文本格式的response信息,在下载文本格式的文件时没啥问题,但是对于binary等非文本格式的文件时就有问题了,这里记录一下解决办法以及产生这个问题的原因,方便以后参考。
正文:
参考解答:
当你想下载一个二进制文件时,不要将 InputStream 嵌入任何的 Reader 类型变量中,而应该是 stream 格式读入,(可以借助于一个字节数组作为缓冲区)然后 stream 格式写出。
如果你在这中间使用了任何类型的 Reader 变量,将内容先转换成了 字符/字符串 再写出至文件,(大概率)就会受到平台编码方式的影响,最后的结果可能就和你预期的不一致了。
If you are trying to read a binary stream, you should NOT wrap the InputStream in a Reader of any kind.Read the data into a byte array buffer using the InputStream.read(byte[], int, int) method. Then write from the buffer to a FileOutputStream.
使用 HttpClient 和 FileUtils.copyInputStreamToFile 以及 FileOutputStream 的方式:
package com.ixyzero.learn.utils;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
/**
* Created by ixyzero on 2019/9/14.
*/
public class DownloadBinaryFile {
// HttpURLConnection download from remote url to local file
public static void httpGetBinary2(String url, File file) {
URL obj = null;
HttpURLConnection con = null;
try {
obj = new URL(url);
con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Mozilla/5.0");
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
InputStream inputStream = con.getInputStream();
byte[] buffer = new byte[4096];
int n;
OutputStream output = new FileOutputStream( file );
while ((n = inputStream.read(buffer)) != -1) {
output.write(buffer, 0, n);
}
output.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
// HttpClient download from remote url to local file
public static void httpGetBinary(String url, File file) {
HttpClient client = HttpClientBuilder.create().build();
// code below adds HTTP REDIRECT support to GET and POST methods
// HttpClient client = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
HttpGet request = new HttpGet(url);
request.addHeader("User-Agent", "Mozilla/5.0");
try {
HttpResponse response = client.execute(request);
System.out.println("Response Code : " + response.getStatusLine().getStatusCode());
InputStream inputStream = response.getEntity().getContent();
FileUtils.copyInputStreamToFile(inputStream, file);
} catch (IOException e) {
e.printStackTrace();
} finally {
//
}
}
public static void main(String[] args) {
DownloadBinaryFile downloader = new DownloadBinaryFile();
String url1 = "https://www.cnblogs.com/images/logo_small.gif";
String filepath1 = "/path/to/logo.gif";
String filepath2 = "/path/to/logo2.gif";
downloader.httpGetBinary(url1, new File(filepath1));
downloader.httpGetBinary2(url1, new File(filepath2));
}
}
参考链接:
=END=