Reputation: 255
How to convert below code to JAVA 8 - try-with-resource. I have written this code in java 6,i have upgraded java 6 to java 8 - Sonar giving Blocker message "Try-with-resources should be used"
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);
}
}
Upvotes: 3
Views: 17024
Reputation: 22402
In order to avoid resource leaks, it is always best practice to close the resource objects (like your FileOutputStream
, etc..) in the finally
block. The reason is that finally block gets executed even upon exception and the resource will never get leaked or escaped.
The important thing in your code is that you are NOT closing the resources in the finally
block i.e., they can escape & produce leaks.
Instead of you closing the resoruces in the finally
block,
try-with-resources is just a syntactic sugar to close any resource class (which implement AutoCloseable
) objects (this is introduced in Java1.7)
You can apply try-with-resources concept as shown below for your code with inline comments:
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);
}
}
I suggest you look here for more details and understand this concept.
Upvotes: 5
Reputation: 728
Here you go.
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);
}
}
Upvotes: 0
Reputation: 72844
A side note: try-with-resources statements were introduced in Java 7.
The resources to be disposed of in this case are the FileOutputStream
, the ZipOutputStream
and the FileInputStream
. Formally speaking, they can be used in try-with-resources because they implement AutoCloseable
. So you can write the code as follows:
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);
}
}
Notice that you don't need to call FileOutputStream.close()
or FileInputStream.close()
.
Why is Sonar telling you to use these statements?
It's because they are the best way to deal with objects that represent resources such as IO streams while ensuring that they are closed at the end. Otherwise, resources may leak in your system. With Java 6 code, the alternative is to use 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();
}
}
You can read about the try-with-resources statement from the Java tutorials: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html.
Upvotes: 2
Reputation: 1202
Additionally I increased the copy buffer. On file system operation the minimum buffer size should be 4094 as this is the block size on most OS/file-systems.
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);
}
}
Upvotes: 0