目录
3、URL.openStream()与HttpURLConnection.getInputStream()的区别
1、开发背景
java利用Freemaker模板引擎生成word导出,导出的数据中包含图片,所以需要先将图片转化为base64码,然后将这些数据输出生成word文件。
承接上篇:java将图片转化为base64码
在本地测试时,没有问题,但是放到服务器环境就会出现图片显示不全的问题,这里边主要涉及读取远程文件和本地文件需要采用不同的策略,详见:java读取本地文件和远程文件
但是导出的word文件依旧出现了类似下图中显示不全的现象,很明显是发生了数据缺失
然后我查看每一句代码,最后锁定在了InputStream.available()
2、 关于InputStream.available()
之所以用InputStream.available()可能就是因为在InputStream和OutStream中用得太顺手了,就像直接套固定公式一样。
用File类将一个文件复制到另一个文件(此处指本地文件)时,通常用InputStream.available()来获取文件的总大小。
但是为什么涉及到远程文件时,InputStream.available()就不是文件总大小了呢??
先看下官方文档说明
翻译一下如下图:
我们知道读取远程文件需要依赖网络环境,这个过程通常是不可控和不稳定的,也就是说read()可能会阻塞,因此不能再采用InputStream.available()。
然后再把思路放在URL上
3、URL.openStream()与HttpURLConnection.getInputStream()的区别
看官方文档即URL.openStream()比HttpURLConnection.getInputStream()多走了一步路
4、改进之后的完整代码
//获得图片的base64码
public static String getImageBase(String src) throws Exception {
URL url = new URL(src);
InputStream in = null;
byte[] data = null;
try {
HttpURLConnection httpconn = (HttpURLConnection)url.openConnection();
//in = url.openStream();//远程文件
in = httpconn.getInputStream();
int i = httpconn.getContentLength();
data = new byte[i];
int readCount=0;
while(readCount<i){//循环读取数据
readCount+=in.read(data,readCount,i-readCount);
}
} catch (IOException e) {
e.printStackTrace();
}
Encoder encoder = Base64.getEncoder();
String s = encoder.encodeToString(data);
in.close();
return s;
}