首页 新闻 赞助 找找看

BufferedOutputStream和FileOutputStream关流问题

0
悬赏园豆:5 [已关闭问题] 关闭于 2018-01-10 08:48

代码如下:

​
    public Map upload(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request){
        if (multipartFile.isEmpty()){
            return ResultData.newError("上传失败,文件是空的。");
        }
        String fileName = multipartFile.getOriginalFilename();
        String filePath = environment.getProperty(UdConstant.RESOURCE_TEMP);
        File folder = new File(filePath);
        if (!folder.exists()){
            folder.mkdirs();
        }
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = new File(filePath + fileName);
        try {
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(multipartFile.getBytes());
        } catch (java.io.IOException e) {
            e.printStackTrace();
        } finally {
            if (null != bos){
                try {
                    bos.flush();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != fos){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 保存待审核资源数据
        ResourceTemp resourceTemp = new ResourceTemp();
        String tokenId = request.getSession().getAttribute(UdConstant.USER_LOGIN_EVIDENCE).toString();
        resourceTemp.setAuthor(redisCache.getUserName(tokenId));
        resourceTemp.setMd5(Md5Util.getFileMD5(file));
        resourceTemp.setDesignation(request.getParameter("designation"));
        resourceTemp.setClassifyId(request.getParameter("classifyId"));
        resourceTemp.setDescription(request.getParameter("description"));
        resourceTemp.setResourceType(request.getParameter("resourceType"));
        resourceTemp.setResourceSize(Double.parseDouble(request.getParameter("resourceSize")));
        Map result = this.resourceTempService.save(resourceTemp);
        if (Integer.valueOf(result.get(UdConstant.RESULT_CODE).toString()) != UdConstant.RESULT_CORRECT_CODE) {
            return result;
        }
        String newFileName = resourceTemp.getId() + fileName.substring(fileName.lastIndexOf("."));
                // 文件重命名
        File renameFile = new File(filePath + newFileName);
        if (!file.renameTo(renameFile)){
            return ResultData.newError("文件重命名失败,请联系管理员改BUG");
        }
        return result;
    }


上面的代码中重命名文件失败了,手动删除的时候提示文件被jvm占用,也就是流没有关,但是我已经在 finally里面关了,于是我把finally改成这样:

            if (null != fos) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != bos){
                try {
                    bos.flush();
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


文件重命名成功了,但是在第二个try抛异常了,说流已经关闭了,看了下源码,它调用的是FileOutputStream的flush,前面已经关了,当然抛异常啦。
于是我看了下BufferedOutputStream的close方法的源码(jdk1.8):

    public void close() throws IOException {
        try (OutputStream ostream = out) {
            flush();
        }
    }
        
        public void flush() throws IOException {
        out.flush();
    }


它只调用了FileOutputStream的flush并没有关闭它,可是我之前先调用了BufferedOutputStream的flush和close再调用了FileOutputStream的close方法,但是结果却没有关流。。。

谁能帮我解答一下吗,不胜感激!!!

VioletGlass的主页 VioletGlass | 菜鸟二级 | 园豆:202
提问于:2018-01-09 23:50
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册