文件写入下载


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. 待补充