最近今天碰到某同学想把一个网址的某gif图片上传到UCloud上,碰到了一个异常:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4096
at com.sun.imageio.plugins.gif.GIFImageReader.read(GIFImageReader.java:984)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at com.sdcuike.IM.main(IM.java:26)
Google了一下,发现从jdk1.6到1.8一直存在这个bug,对某些gif图片(想免费翻墙去:https://my.ishadowx.net,不过一封,域名就会变)。
UCloud sdk也支持本地文件上传,由于不想把文件下载到本地。
报错的部分代码:
final URL url = new URL("https://mmbiz.qpic.cn/mmbiz_gif/qwxf4wHyyTEqj4b8VeF3X0YEPUaPlicb5m8boreNZH9EkL8M3VHRyrhsBG84nuImBqbhLhxFUj9oSvPmGIFxZzA/640?wx_fmt=gif");
final BufferedImage read = ImageIO.read(url);
想着把改文件读到byte数组中后,再操作。还好,url有方法:
java.net.URL#openStream
不过,java.io.InputStream#available 方法,最好不要用来获取读取到的文件的大小了,也是一个坑吧。所以,我们对流读取到的数组进行操作,包括文件的大小。
具体代码:
package com.sdcuike;
import cn.ucloud.ufile.UFileClient;
import cn.ucloud.ufile.UFileRequest;
import cn.ucloud.ufile.UFileResponse;
import cn.ucloud.ufile.sender.PutSender;
import com.missfresh.sdk.ucloud.UcloudConfig;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URL;
/**
* @author sdcuike
* @date 2018/6/8
* @since 2018/6/8
*/
public class IM {
public static void main(String[] args) throws IOException, InterruptedException {
final URL url = new URL("https://mmbiz.qpic.cn/mmbiz_gif/qwxf4wHyyTEqj4b8VeF3X0YEPUaPlicb5m8boreNZH9EkL8M3VHRyrhsBG84nuImBqbhLhxFUj9oSvPmGIFxZzA/640?wx_fmt=gif");
byte[] bytes = IOUtils.toByteArray(url);
final String fileNmae = "txt.gif";
UFileClient ufileClient = null;
try {
UFileRequest request = new UFileRequest();
request.setBucketName(UcloudConfig.BUCKET_DEVELOP);
request.setKey(fileNmae);
request.setContentLength(bytes.length);
request.setInputStream(new ByteArrayInputStream(bytes));
request.addHeader("X-UCloud-World", "world");
request.addHeader("X-UCloud-Hello", "hello");
ufileClient = new UFileClient();
ufileClient.setConfigPath(UcloudConfig.UCloudPublicKey, UcloudConfig.UCloudPrivateKey,
UcloudConfig.ProxySuffix, UcloudConfig.DownloadProxySuffix);
PutSender sender = new PutSender();
sender.makeAuth(ufileClient, request);
UFileResponse response = sender.send(ufileClient, request);
final String s = "https://j-image.missfresh.cn/" + fileNmae;
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (ufileClient != null) {
ufileClient.shutdown();
}
}
}
}
看一下:https://j-image.missfresh.cn/txt.gif
是不是有gif上传成功了。
后记:ImageIO.read 读取某些gif图片会报错,是个bug,所以换个方式,对流读取到byte数组中,后续的操作及文件大小都以此byte数组为准。