如何将以下代码转换为JAVA 8 - try-with-resource。我已经在java 6中编写了这段代码,我已经将java 6升级到java 8 - Sonar给出Blocker消息“应该使用资源试用”
VK_LAYER_LUNARG_core_validation
答案 0 :(得分:2)
附注:Java 7中引入了try-with-resources语句。
在这种情况下要处理的资源是FileOutputStream
,ZipOutputStream
和FileInputStream
。从形式上讲,它们可以在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);
}
}