项目有一个需求是:
从网上下载图片,并用BASE64 转为字符串发送给别人。
从网上看了很多,我最终主要是 用
sun.misc.BASE64Decoder 和 sun.misc.BASE64Encoder 实现
代码如下:
package ins.platform.web.utils; import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * * @Description: 下载图片 * @author: * @date: 2018年1月5日 上午11:31:05 * @version V1.0 * @Copyright: 2018 www.newtouch.cn . All rights reserved. * */ public class PictureDownLoadUtil { private static final Logger LOGGER = LoggerFactory.getLogger(PictureDownLoadUtil.class); private static final int PROTECTED_LENGTH = 1024 * 1024;// 输入流保护 1M public static String downLoad(String strUrl, Boolean isProxy, String host, String port) { if (isProxy) { setProxy(host, port); } URL url = null; try { url = new URL(strUrl); } catch (MalformedURLException e2) { LOGGER.error("下载图片异常,新建URL失败"); return ""; } InputStream is = null; try { is = url.openStream(); return readInfoStreamToBytes(is); } catch (IOException e1) { LOGGER.error("下载图片异常"); return ""; } } public static void setProxy(String host, String port) { System.setProperty("proxySet", "true"); System.setProperty("proxyHost", host); System.setProperty("proxyPort", port); } public static void main(String[] args) { String str = "http://7xrnr1.com1.z0.glb.clouddn.com/090406.png"; String picStr = PictureDownLoadUtil.downLoad(str, true, "", ""); GenerateImage(picStr); System.out.print(picStr); } public static boolean GenerateImage(String imgStr) { // 对字节数组字符串进行Base64解码并生成图片 if (imgStr == null) // 图像数据为空 return false; BASE64Decoder decoder = new BASE64Decoder(); try { // Base64解码 byte[] b = decoder.decodeBuffer(imgStr); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) {// 调整异常数据 b[i] += 256; } } // 生成jpeg图片 String imgFilePath = "d://qq.jpg";// 新生成的图片 OutputStream out = new FileOutputStream(imgFilePath); out.write(b); out.flush(); out.close(); return true; } catch (Exception e) { return false; } } public static String readInfoStreamToBytes(InputStream is) { if (is == null) { LOGGER.error("输入流为null"); return null; } // 字节数组 byte[] bCache = new byte[2048]; int readSize = 0;// 每次读取的字节长度 int totalSize = 0;// 总字节长度 ByteArrayOutputStream infoStream = new ByteArrayOutputStream(); try { // 一次性读取2048字节 while ((readSize = is.read(bCache)) > 0) { totalSize += readSize; if (totalSize > PROTECTED_LENGTH) { LOGGER.error("输入流超出1M大小限制"); return null; } // 将bcache中读取的input数据写入infoStream infoStream.write(bCache, 0, readSize); } } catch (IOException e1) { LOGGER.error("输入流读取异常"); return null; } finally { try { is.close(); } catch (IOException e) { LOGGER.error("输入流关闭异常"); } } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(infoStream.toByteArray()); } }
需要说明的是:
1.在eclipse中无法直接使用Base64Encoder
原来Base64Encoder并不属于JDK标准库范畴,但是又包含在了JDK中,如http://moses3017.iteye.com/blog/968854所言。
解决方法:按照如下方法设置 Eclipse导入%JAVA_HOME%\jre\lib目录下的rt.jar包即可。
Project->Properties,选择Java Build Path设置项,再选择Libraries标签,Add External Jars添加%JAVA_HOME%\jre\lib\rt.jar就可以使用啦!
2.我本地的环境是内网,需要设置代理访问外网
public static void setProxy(String host, String port) { System.setProperty("proxySet", "true"); System.setProperty("proxyHost", host); System.setProperty("proxyPort", port); }
3.网上看到不少地方有这样的代码:
/** * 图片转化成base64字符串 * @param inputFile 源图片文件路径 * @return */ public static String getImageStr(File inputFile) throws Exception{// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理 InputStream in = null; byte[] data = null; // 读取图片字节数组 in = new FileInputStream(inputFile); data = new byte[in.available()]; in.read(data); in.close(); // 对字节数组Base64编码 BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(data);// 返回Base64编码过的字节数组字符串 }
我刚开始也是这样写的,后面下载的图片一直下载不完全。就是上半部分。
可能跟用URL下载图片和从本地读取图片有关,最后是这样实现的
public static String readInfoStreamToBytes(InputStream is) { if (is == null) { LOGGER.error("输入流为null"); return null; } // 字节数组 byte[] bCache = new byte[2048]; int readSize = 0;// 每次读取的字节长度 int totalSize = 0;// 总字节长度 ByteArrayOutputStream infoStream = new ByteArrayOutputStream(); try { // 一次性读取2048字节 while ((readSize = is.read(bCache)) > 0) { totalSize += readSize; if (totalSize > PROTECTED_LENGTH) { LOGGER.error("输入流超出1M大小限制"); return null; } // 将bcache中读取的input数据写入infoStream infoStream.write(bCache, 0, readSize); } } catch (IOException e1) { LOGGER.error("输入流读取异常"); return null; } finally { try { is.close(); } catch (IOException e) { LOGGER.error("输入流关闭异常"); } } BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(infoStream.toByteArray()); }