文件写入下载
1. 文件写入
FileWriter是对文件进行写操作的字符流,继承自Writer。由于与系统文件资源相关的操作,都容易发生异常。所以在进行FileWriter进行文件的操作时,需要进行try\catch处理;另外,开辟流之后,在最后的操作都应该对流进行关闭,即执行close()方法,所以一般将close()方法放入finally语句块中。
File file = new File(path+fileName); FileWriter fileWriter=null; //保存文件 try { File parent = file.getParentFile(); // 获取父文件 if( !parent.exists() ){ parent.mkdirs();} //创建所有父文件夹 if (!file.exists()){ file.createNewFile(); } fileWriter = new FileWriter(file); for (int i=0;i<5;i++){ fileWriter.write("啦啦啦啦~"); //换行 fileWriter.write(System.getProperty("line.separator")); } fileWriter.flush(); fileWriter.close(); }catch (IOException e){ e.printStackTrace(); }finally { try { if(fileWriter!=null) fileWriter.close(); } catch (Exception e1) { e1.printStackTrace(); } }
2.文件下载
@RequestMapping(value = {"exportSNText"}, method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8) public HttpServletResponse creatSN(String fileName, HttpServletResponse response) { String path="/xxx/xxxx/"+fileName; InputStream fis =null; FileInputStream inputStream=null; try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); // 取得文件的后缀名。 String ext = filename.substring(filename.lastIndexOf(".") + 1).toUpperCase(); // 以流的形式下载文件。 inputStream = new FileInputStream(path); fis = new BufferedInputStream(inputStream); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); inputStream.close(); // 清空response response.reset(); // 设置response的Header response.addHeader("Content-Disposition", "attachment;filename=" +URLEncoder.encode(filename) ); response.addHeader("Content-Length", "" + file.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); }finally { try { if(fis!=null) fis.close(); } catch (Exception e1) { e1.printStackTrace(); } try { if(inputStream!=null) inputStream.close(); } catch (Exception e1) { e1.printStackTrace(); } } return response; }
由于拦截器或日志的打印,报了些许bug但不影响使用(It is invalid to call isReady() when the response has not been put into non-。。。)
解决办法:
@ResponseBody @RequestMapping(value = {"exportSNText"}, method = RequestMethod.GET, produces = MediaTypes.JSON_UTF_8) public void creatSN(String fileName) { String path="/opt/uuwifi/data/vifiSN/"+fileName; File file = new File(path); if(!file.exists()){ logger.error("file not found"); return; } ActionUtils.downloadFile( file ); }
/** * 下载-通用类 * * @param file * @return result * null:下载成功; * msg:返回的错误信息; * @Description: 文件下载方法 */ public static void downloadFile(File file){ String fileName = file.getName(); try { fileName = URLEncoder.encode(fileName, "UTF-8"); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } ActionUtils.getResponse().setContentType("application/zip"); ActionUtils.getResponse().addHeader("Content-Disposition", "attachment;filename=" + fileName); OutputStream outp = null; FileInputStream in = null; try { outp = ActionUtils.getResponse().getOutputStream(); in = new FileInputStream(file); byte[] b = new byte[1024]; int i = 0; while ((i = in.read(b)) > 0) { outp.write(b, 0, i); } outp.flush(); } catch (Exception e) { // throw new IOException(e); e.printStackTrace(); // return e.getMessage(); } finally { if (in != null) { try { in.close(); in = null; } catch (IOException e) { e.printStackTrace(); } } if (outp != null) { try { outp.close(); outp = null; } catch (IOException e) { e.printStackTrace(); } } } // return null; }
3. 前端下载方法:访问2接口,注意url中传递的参数带有加号+,会被浏览器转换成空格,这样会导致后台获取到无效的参数。这时我们可以使用encodeURIComponent方法先转码,然后再在浏览器中打开。这个问题在使用加密工具加密参数后再传参时是很常见的,因为加密后的字符串里面经常带有加号+。
window.location.href = "/xxx/exportSNText?fileName=" + encodeURIComponent(fileName);
4. 待补充