求大神来看,一个ImageIO读取png,gif出错读取jpg却正常的问题
最近接到一个需求是扫描文件系统里的图片显示在浏览器,使用的jdk7的nio实现的,但是出了点问题.
以下第一个方法是将图片的图片名作为key,图片数据的byte[]作为value放入map,第二个方法是将File对象作为value放入map,之后控制器取到map里的一个特定File或者byte[]进行传参,传给ImageIO.read()方法,但是传File的话读取都正常,传ByteArrayInputStream(byte[] b)时候,图片只要是png和gif就会报错,异常在最下。
public static Map<String,byte[]> getImageMap(String path){
//入参为路径和图片个数的估算最大值
long start = System.currentTimeMillis();
Path p = Paths.get(path);
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(p, "*.{jpg,png,gif}")) {
for (Path entry: stream) {
result.add(entry);
}
} catch (DirectoryIteratorException | IOException e) {
e.printStackTrace();
}
//制定hashmap的容量,防止rehashing的巨大开销
Map<String,byte[]> map = Maps.newHashMapWithExpectedSize(result.size()+50);
InputStream input = null;
BufferedInputStream b = null;
ByteArrayOutputStream out = null;
BufferedOutputStream o = null;
String fileName = null;
String filePath = null;
for(Path currentPath:result ){
if(Files.isReadable(currentPath)){
try{
input = Files.newInputStream(currentPath, StandardOpenOption.READ);
b = new BufferedInputStream(input);
out = new ByteArrayOutputStream();
o = new BufferedOutputStream(out);
fileName = currentPath.getFileName().toString();
//System.out.println("============文件名=================="+fileName);
//currentPath.
byte[] transition = new byte[1024];
int i = 0;
while((i=b.read(transition))!=-1){
o.write(transition);
}
map.put(fileName, out.toByteArray());
}catch(IOException e){
e.printStackTrace();
}finally{
if(b!=null){
try {
b.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(input!=null){
try {
input.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(o!=null){
try {
o.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(out!=null){
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}else{
}
}
long end = System.currentTimeMillis();
System.out.println("时间差================"+(end-start));
return map;
}
public static Map<String,File> getImageMap1(String path){
//入参为路径和图片个数的估算最大值
long start = System.currentTimeMillis();
Path p = Paths.get(path);
List<Path> result = new ArrayList<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(p, "*.{jpg,png,gif}")) {
for (Path entry: stream) {
result.add(entry);
}
} catch (DirectoryIteratorException | IOException e) {
e.printStackTrace();
}
//制定hashmap的容量,防止rehashing的巨大开销
Map<String,File> map = Maps.newHashMapWithExpectedSize(result.size()+50);
String fileName = null;
String filePath = null;
for(Path currentPath:result ){
if(Files.isReadable(currentPath)){
try{
fileName = currentPath.getFileName().toString();
map.put(fileName, currentPath.toFile());
}finally{
}
}else{
}
}
long end = System.currentTimeMillis();
System.out.println("时间差================"+(end-start));
return map;
}
以下注释掉的是控制器的第一套流程,就是出错的那套流程,以ByteArrayInputStream作为参数传给ImageIO.read
@RequestMapping("/picture/single")
public void findImages(HttpServletRequest request,HttpServletResponse response){
String name = request.getParameter("extension");
Assert.notNull(name);
String extension = name.substring(name.indexOf("."));
String ext = extension.substring(1);
if("jpg".equals(ext)||"jpeg".equals(ext)){
response.setContentType("image/jpeg; charset=utf-8");
}else{
response.setContentType("image/"+ext+"; charset=utf-8");
}
HttpSession session = request.getSession();
if(session==null){
throw new RuntimeException("session丢失,请重载页面");
}
//Map<String,byte[]> map = (Map<String,byte[]>)session.getAttribute("images");
//byte[] bytes = map.get(name);
//ByteArrayInputStream imageStream = new ByteArrayInputStream(bytes);
Map<String,File> map = (Map<String,File>)session.getAttribute("images");
File file = map.get(name);
BufferedImage image = null;
OutputStream out = null;
try {
out = response.getOutputStream();
//image = ImageIO.read(imageStream);
image = ImageIO.read(file);
ImageIO.write(image, ext, out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(out!=null){
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*if(imageStream!=null){
try {
imageStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
} 异常如下:
javax.imageio.IIOException: Error reading PNG image data
at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1308)
at com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1577)
at javax.imageio.ImageIO.read(ImageIO.java:1448)
at javax.imageio.ImageIO.read(ImageIO.java:1352)
at cn.com.blossomframework.services.controller.ServiceManagementController.findImages(ServiceManagementController.java:453)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:527)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:423)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:493)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:225)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:930)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:358)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:866)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:245)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:113)
at org.eclipse.jetty.server.Server.handle(Server.java:351)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:594)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1042)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:549)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:211)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:424)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:506)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:436)
at java.lang.Thread.run(Thread.java:724)
aused by: java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at java.io.DataInputStream.readFully(DataInputStream.java:195)
at com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1092)
at com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1196)
at com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1301)
... 43 more
虽然传File是可以,但是还是有道坎,求大神解答!!!