应该使用try-with-resources

时间:2017-04-03 17:26:06

标签: java

如何将以下代码转换为JAVA 8 - try-with-resource。我已经在java 6中编写了这段代码,我已经将java 6升级到java 8 - Sonar给出Blocker消息“应该使用资源试用”

VK_LAYER_LUNARG_core_validation

4 个答案:

答案 0 :(得分:2)

附注:Java 7中引入了try-with-resources语句。

在这种情况下要处理的资源是FileOutputStreamZipOutputStreamFileInputStream。从形式上讲,它们可以在try-with-resources中使用,因为它们实现了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()

为什么声纳会告诉您使用这些声明?

这是因为它们是处理代表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教程中的try-with-resources语句:https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

答案 1 :(得分:2)

为了避免资源泄漏,最好在FileOutputStream块中关闭资源对象(例如finally等)。原因是即使在异常时也会执行finally块,资源永远不会被泄露或转义

您的代码中最重要的一点是,您不会关闭finally块中的资源,即它们可以逃脱&产生泄漏。

而不是关闭finally块中的resoruces, try-with-resources只是关闭任何资源类(实现AutoCloseable)对象的语法糖(这是在Java1.7中引入的)

您可以使用内联注释为您的代码应用 try-with-resources 概念,如下所示:

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了解更多详情并理解这个概念。

答案 2 :(得分: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);
    }
}

答案 3 :(得分: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);
    }
}