2017-04-03 93 views
1

如何将以下代码转换为JAVA 8 - 尝试使用资源。我已经在Java 6中这样写代码,我已经升级的Java 6到Java 8 - 声纳给拦截消息“尝试 - 以资源应使用”应尝试使用资源

public void archivingTheFile(String zipFile){ 
    byte[] buffer = new byte[1024]; 
    try{ 
     FileOutputStream fos = new FileOutputStream(zipFile); 
     ZipOutputStream zos = new ZipOutputStream(fos); 
     for(String file : this.fileList){ 
      ZipEntry ze= new ZipEntry(file); 
      zos.putNextEntry(ze); 
      FileInputStream in = new FileInputStream(SOURCE_FOLDER + File.separator + file); 
      int len; 
      while ((len = in.read(buffer)) > 0) { 
       zos.write(buffer, 0, len); 
      } 
      in.close(); 
     } 
     zos.closeEntry(); 
     zos.close(); 
    }catch(IOException ex){ 
     LOGGER.error("Exception occurred while zipping file",ex); 
    } 
} 

回答

1

为了避免资源泄漏,它始终是最好的做法在finally块,关闭资源对象(如您FileOutputStream,等等)。原因是,即使例外,finally块也会被执行,并且资源将永远不会泄漏或逃脱

代码中的重要事情是,您没有关闭finally块中的资源,即它们可以转义&产生泄漏。

而不是你在finally块关闭resoruces, 试穿与资源只是一个语法糖收任何资源类(实现AutoCloseable)对象(这是在Java1.7引入)

你可以申请试穿与资源概念,作为你的代码行内注释如下所示:

public void archivingTheFile(String zipFile){ 
      byte[] buffer = new byte[1024]; 

      //wrap the resources inside try(....) 
      try(FileOutputStream fos = 
         new FileOutputStream(zipFile); 
        ZipOutputStream zos = new ZipOutputStream(fos);) { 
       for(String file : this.fileList){ 
        ZipEntry ze= new ZipEntry(file); 
        zos.putNextEntry(ze); 

        //wrap this resource as well inside try(....) 
        try(FileInputStream in = 
         new FileInputStream(SOURCE_FOLDER + File.separator + file)){ 
         int len; 
         while ((len = in.read(buffer)) > 0) { 
          zos.write(buffer, 0, len); 
         } 
        } catch(IOException ex) { 
         LOGGER.error("Exception occurred while zipping file",ex); 
        } 
       } 
      }catch(IOException ex){ 
       LOGGER.error("Exception occurred while zipping file",ex); 
      } 
     } 

我建议你看看here更多d了解这个概念。

1

一个侧面说明:尝试与 - 资源语句是在Java 7中引入。

在这种情况下要处理的资源是FileOutputStreamZipOutputStreamFileInputStream。从形式上讲,它们可以用于试用资源,因为它们实现AutoCloseable。所以,你可以写出如下代码:

的Java 7+

public void archivingTheFile(String zipFile){ 
    byte[] buffer = new byte[1024]; 
    try(FileOutputStream fos = new FileOutputStream(zipFile); 
     ZipOutputStream zos = new ZipOutputStream(fos)) { 
     for(String file : this.fileList){ 
      ZipEntry ze= new ZipEntry(file); 
      zos.putNextEntry(ze); 
      try(FileInputStream in = new FileInputStream(SOURCE_FOLDER + File.separator + file)) { 
       int len; 
       while ((len = in.read(buffer)) > 0) { 
        zos.write(buffer, 0, len); 
       } 
      } 
     } 
     zos.closeEntry(); 

    }catch(IOException ex){ 
     LOGGER.error("Exception occurred while zipping file",ex); 
    } 
} 

请注意,您不需要调用FileOutputStream.close()FileInputStream.close()

为什么Sonar会告诉你使用这些语句?

这是因为它们是处理表示资源的对象的最佳方式,例如IO流,同时确保它们在末尾处关闭。否则,资源可能会泄漏到您的系统中。在Java 6的代码,另一种方法是使用try-catch-finally

的Java 6

FileOutputStream fos = null; 
ZipOutputStream zos = null; 
try { 
    fos = new FileOutputStream(zipFile); 
    zos = new ZipOutputStream(fos) 
    ... 
} catch(IOException ex){ 
    LOGGER.error("Exception occurred while zipping file",ex); 
} finally { 
    if(fos != null) { 
     fos.close(); 
    } 
    if(zos != null) { 
     zos.close(); 
    } 
} 

你可以阅读从Java教程的尝试,与资源声明:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

+1

参考:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – gba

0

此外我增加了复制缓冲区。在文件系统操作上,最小缓冲区大小应该是4094,因为这是大多数OS /文件系统上的块大小。

public void archivingTheFile(String zipFile) { 
    byte[] buffer = new byte[4096]; 
    try (FileOutputStream fos = new FileOutputStream(zipFile); ZipOutputStream zos = new ZipOutputStream(fos)) { 

     for (String file : this.fileList) { 
      ZipEntry ze = new ZipEntry(file); 
      zos.putNextEntry(ze); 
      try (FileInputStream in = new FileInputStream(SOURCE_FOLDER + File.separator + file)) { 
       int len; 
       while ((len = in.read(buffer)) > 0) { 
        zos.write(buffer, 0, len); 
       } 
      } 
     } 
     zos.closeEntry(); 
    } catch (IOException ex) { 
     LOGGER.error("Exception occurred while zipping file", ex); 
    } 
} 
0

你在这里。

public void archivingTheFile(String zipFile){ 
byte[] buffer = new byte[1024]; 
    try (FileOutputStream fos = new FileOutputStream(zipFile); 
     ZipOutputStream zos = new ZipOutputStream(fos)) { 
     for(String file : this.fileList){ 
      ZipEntry ze = new ZipEntry(file); 
      zos.putNextEntry(ze); 
      try (FileInputStream in = new FileInputStream(SOURCE_FOLDER + File.separator + file)) { 
       int len; 
       while ((len = in.read(buffer)) > 0) { 
        zos.write(buffer, 0, len); 
       } 
      } 
     } 
     zos.closeEntry(); 
    } catch(IOException ex){ 
     LOGGER.error("Exception occurred while zipping file",ex); 
    } 
}