javax异常: javax.imageio.IIOException: Can't create output stream解决方法

简介: javax异常: javax.imageio.IIOException: Can't create output stream解决方法


  • 验证码工具类:

 

1

packagecom.newcapec.utils;

2

3

importcom.sun.image.codec.jpeg.JPEGCodec;

4

importcom.sun.image.codec.jpeg.JPEGImageEncoder;

5

6

importjava.awt.*;

7

importjava.awt.image.BufferedImage;

8

importjava.io.FileOutputStream;

9

importjava.io.IOException;

10

importjava.io.OutputStream;

11

importjava.util.Random;

12

13

/**

14

* <p>Title: ValidateCode.java</p>  

15

* <p>Description: 验证码工具类</p>  

16

*/

17

publicclassValidateCode {    

18

   // 图片的宽度。  

19

   privateintwidth=120;  

20

   // 图片的高度。  

21

   privateintheight=40;  

22

   // 验证码字符个数  

23

   privateintcodeCount=4;  

24

   // 验证码干扰线数  

25

   privateintlineCount=30;  

26

   // 验证码  

27

   privateStringcode=null;  

28

   // 验证码图片Buffer  

29

   privateBufferedImagebuffImg=null;  

30

 

31

   privatechar[] codeSequence= { 'A','a', 'B','b', 'C','c', 'D','d', 'E','e', 'F','f', 'g','H','h',  

32

           'J','j', 'K','k','L', 'M','m', 'N','n', 'P','p', 'Q','q', 'R','r', 'S','s', 'T', 'U','u', 'V', 'W','w',  

33

           'X','x', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9'};  

34

 

35

   // 生成随机数  

36

   privateRandomrandom=newRandom();  

37

 

38

   publicValidateCode() {  

39

       this.createCode();  

40

   }  

41

 

42

   /**

43

    *  

44

    * @param width

45

    *            图片宽

46

    * @param height

47

    *            图片高

48

    */  

49

   publicValidateCode(intwidth, intheight) {  

50

       this.width=width;  

51

       this.height=height;  

52

       this.createCode();  

53

   }  

54

 

55

   /**

56

    *  

57

    * @param width

58

    *            图片宽

59

    * @param height

60

    *            图片高

61

    * @param codeCount

62

    *            字符个数

63

    * @param lineCount

64

    *            干扰线条数

65

    */  

66

   publicValidateCode(intwidth, intheight, intcodeCount, intlineCount) {  

67

       this.width=width;  

68

       this.height=height;  

69

       this.codeCount=codeCount;  

70

       this.lineCount=lineCount;  

71

       this.createCode();  

72

   }  

73

 

74

   publicvoidcreateCode() {  

75

       RandomheightRandom=newRandom();

76

       intcodeX=0;  

77

       intfontHeight=0;  

78

       fontHeight=height-heightRandom.nextInt(7)-7;// 字体的高度  

79

       codeX=width/ (codeCount+1);// 每个字符的宽度  

80

 

81

       // 图像buffer  

82

       buffImg=newBufferedImage(width, height, BufferedImage.TYPE_INT_RGB);  

83

       Graphics2Dg=buffImg.createGraphics();  

84

 

85

       // 将图像填充为白色  

86

       g.setColor(Color.WHITE);  

87

       g.fillRect(0, 0, width, height);  

88

 

89

       // 创建字体  

90

       ImgFontByteimgFont=newImgFontByte();  

91

       Fontfont=imgFont.getFont(fontHeight);  

92

       g.setFont(font);  

93

 

94

       // 绘制干扰线  

95

       for (inti=0; i<lineCount; i++) {  

96

           intxs=getRandomNumber(width);  

97

           intys=getRandomNumber(height);  

98

           intxe=xs+getRandomNumber(width/8);  

99

           intye=ys+getRandomNumber(height/8);  

100

           g.setColor(getRandomColor());  

101

           g.drawLine(xs, ys, xe, ye);  

102

       }  

103

 

104

       

105

       StringBufferrandomCode=newStringBuffer();  

106

       

107

//        int x = 5;

108

       // 随机产生验证码字符  

109

       for (inti=0; i<codeCount; i++) {

110

           inth=height-8;

111

           intw= (i+1) *codeX+heightRandom.nextInt(4);

112

           StringstrRand=String.valueOf(codeSequence[random  

113

                   .nextInt(codeSequence.length)]);  

114

           // 设置字体颜色  

115

           g.setColor(getRandomColor());  

116

117

           intdegree=newRandom().nextInt() %10;

118

           g.rotate(degree*Math.PI/180,(w+codeX-5)/2, (h+fontHeight)/2);

119

           // 设置字体位置  

120

           g.drawString(strRand, w, h );  //getRandomNumber(height / 2) + 25

121

           g.rotate(-degree*Math.PI/150, (w+codeX-5)/2, (h+fontHeight)/2);

122

           randomCode.append(strRand);  

123

       }  

124

       code=randomCode.toString();  

125

   }  

126

 

127

   /** 获取随机颜色 */  

128

   privateColorgetRandomColor() {  

129

       intr=getRandomNumber(225);  

130

       intg=getRandomNumber(225);  

131

       intb=getRandomNumber(225);  

132

       returnnewColor(r, g, b);  

133

   }

134

 

135

   /** 获取随机数 */  

136

   privateintgetRandomNumber(intnumber) {  

137

       returnrandom.nextInt(number);  

138

   }  

139

 

140

   publicvoidwrite(Stringpath) throwsIOException {  

141

       OutputStreamsos=newFileOutputStream(path);  

142

       this.write(sos);  

143

   }  

144

 

145

   publicvoidwrite(OutputStreamsos) throwsIOException {  

146

//         ImageIO.write(buffImg, "png", sos);

147

       JPEGImageEncoderencoder=JPEGCodec.createJPEGEncoder(sos);

148

       encoder.encode(buffImg);

149

       sos.close();  

150

   }  

151

 

152

   publicBufferedImagegetBuffImg() {  

153

       returnbuffImg;  

154

   }  

155

 

156

   publicStringgetCode() {  

157

       returncode;  

158

   }  

159

 

160

   /** 字体样式类 */  

161

   classImgFontByte {

162

       publicFontgetFont(intfontHeight) {  

163

           returnnewFont("Arial", Font.PLAIN, fontHeight);

164

       }  

165

   }  

166

   

167

   

168

}

169


  • 使用

 

1

publicvoidscaptcha(){

2

       HttpServletResponseresponse=ServletActionContext.getResponse();

3

       response.reset();

4

       // 设置响应的类型格式为图片格式  

5

       response.setContentType("image/jpeg");  

6

       // 禁止图像缓存。  

7

       response.setHeader("Pragma", "no-cache");  

8

       response.setHeader("Cache-Control", "no-cache");  

9

       response.setDateHeader("Expires", 0);  

10

       ValidateCodeinstance=newValidateCode();

11

       CookieUtil.setCookie(response, "scaptcha", instance.getCode().toUpperCase(), null, -1);

12

       try {

13

           instance.write(response.getOutputStream());

14

       } catch (IOExceptione) {

15

           e.printStackTrace();

16

       }

17

   }



在使用ImageIO.write时,发现在Linux平台上,会出现异常:

 

1

javax.imageio.IIOException: Can't create output stream

 

1

检查tomcat的日志,终于真相大白:

2

3

javax.imageio.IIOException: Can't create output stream!

4

5

atjavax.imageio.ImageIO.write(ImageIO.java:1521)

6

7

Causedby: javax.imageio.IIOException: Can't create cache file!

8

9

atjavax.imageio.ImageIO.createImageOutputStream(ImageIO.java:395)

10

11

atjavax.imageio.ImageIO.write(ImageIO.java:1519)

12

13

... 34more

14

Causedby: java.io.IOException: 系统找不到指定的路径。

15

16

原来是ImageIO.write(image, "jpeg", response.getOutputStream());


查看日志,发现是由找不到文件引起

 

1

Java.nio.file.NoSuchFileException: xxx.../temp/imageio4138671232726624650.tmp


  • 主要原因如下:

在使用ImageIO进行图片写操作时,默认会使用缓存目录:${tomcat}/temp,在此缓存目录会生成缓存文件imageio4138671232726624650.tmp(这一串数字应该是当前时间戳,临时文件名),有些生产环境的tomcat,会将temp目录删除,因此报错


  • 4种解决方法如下:

  1. 在tomcat下新建temp目录;
  2. 与方法1相似,通过ImageIO.setCacheDirectory(cacheDirectory);设置任意的、存在的缓存目录
  3. ImageIO默认是使用缓存目录,可以通过ImageIO.setUseCache(false)来设置,更改缓存策略,不使用文件目录缓存,使用内存缓存
  4. 不使用ImageIO,换成其它JDK方法

 

1

ImageIO.write(bi, "jpg", baos);

2

换成:

3

JPEGImageEncoderencoder=JPEGCodec.createJPEGEncoder(response.getOutputStream());

4

encoder.encode(image);


目录
相关文章
|
网络安全
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "http://xxxx.svc.cluster.local:8080/xxxx": Connection reset; nested exception is java.net.SocketException: Connection reset 什么原因导致得
Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "xxxx.svc.cluster.local:8080/xxxx ": Connection reset; nested exception is java.net.SocketException: Connection reset 什么原因导致得
2028 0
|
缓存 应用服务中间件 Apache
javax.imageio.IIOException: Can‘t create output stream!(验证码图片不显示)
javax.imageio.IIOException: Can‘t create output stream!(验证码图片不显示)
|
5月前
|
Java 应用服务中间件
已解决:An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream canno
已解决:An error occurred at line: 1 in the generated java file The type java.io.ObjectInputStream canno
104 0
|
Java 应用服务中间件
线上临时文件夹报错Failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.nio.file.NoSuchFileException
Failed to parse multipart servlet request; nested exception is java.lang.RuntimeException: java.nio.file.NoSuchFileException、tmp、配置文件指定目录
213 0
|
缓存 Java Spring
【异常】com.alicp.jetcache.support.CacheEncodeException: Java Encode error.
【异常】com.alicp.jetcache.support.CacheEncodeException: Java Encode error.
181 0
|
6月前
|
Java Spring
上传文件出现 aximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.
上传文件出现 aximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.
49 0
|
前端开发 Java Spring
解决Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/Servlet
解决Caused by: java.io.FileNotFoundException: Could not open ServletContext resource [/WEB-INF/Servlet
338 0
|
缓存 监控 Linux
写入图片抛出java.io.IOException: Broken pipe异常
关于写入图片抛出java.io.IOException: Broken pipe异常的问题
495 1
SpringBoot项目中使用request.getInputStream()获取参数时出现java.io.IOException: Stream closed
@RequestBody注解会先调用request.getInputStream()这个方法获取参数,然而request.getInputStream()这个流只能被读取一次,所以我们再次读取这个流就会报错。 解决方案: 最简单的方案就是 先读取流,然后在将流写进去就行了