Create intermediate folders if one doesn't exist - java

I am trying to create a folder for each username a user logs in as. Currently I have
private String destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user
but the File theFile bit does not create a new folder for the username. How would I do this ?
I have tried
private String destination;
public void File()
{
destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
theFile.mkdirs();
}
but I need to use the destination later on in the program, how would I do that?
This is my whole code:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package richard.fileupload;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import java.io.File;
import org.primefaces.event.FileUploadEvent;
#ViewScoped
#ManagedBean(name = "fileUploadController")
public class FileUploadController {
/*
public void handleFileUpload(FileUploadEvent event) {
System.out.println("called");
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
*/
private String username;
private String destination;
#PostConstruct
public void init() {
System.out.println("called get username");
username = FacesContext.getCurrentInstance().getExternalContext().getRemoteUser();
}
public void File() {
destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + username); // will create a sub folder for each user (currently does not work, below hopefully is a solution)
theFile.mkdirs();
}
public File getDirectory(String destination, String username) {
System.out.println("called get directory");
// currently not working, is not calling the username or destination
//set the user directory from the destinarion and the logged user name
File directory = new File(destination, username);
//check if the location exists
if (!directory.exists()) {
//let's try to create it
try {
directory.mkdir();
} catch (SecurityException secEx) {
//handle the exception
secEx.printStackTrace(System.out);
directory = null;
}
}
return directory;
}
public void handleFileUpload(FileUploadEvent event) {
System.out.println("called handle file");
FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded."); //Displays to user on the webpage
FacesContext.getCurrentInstance().addMessage(null, msg);
try {
copyFile(event.getFile().getFileName(), event.getFile().getInputstream());
} catch (IOException e) {
//handle the exception
e.printStackTrace();
}
}
public void copyFile(String fileName, InputStream in) {
try {
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination + fileName)); // cannot find path when adding username atm
System.out.println("Called CopyFile"); //testing
System.out.println(destination + fileName);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");//testing
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("The files were not uploaded!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
}
FINAL EDIT (Hopefully)
public void copyFile(String fileName, InputStream in) {
try {
destination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/"; // main location for uploads
File theFile = new File(destination + "/" + username);
theFile.mkdirs();// will create a sub folder for each user (currently does not work, below hopefully is a solution) (DOES NOW WORK)
System.out.println("Completed File");
// write the inputStream to a FileOutputStream
OutputStream out = new FileOutputStream(new File(destination + fileName)); // cannot find path when adding username atm
System.out.println("Called CopyFile"); //testing
System.out.println(destination + fileName);
int read = 0;
byte[] bytes = new byte[1024];
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
in.close();
out.flush();
out.close();
//make sure new file is created, (displays in glassfish server console not to end user)
System.out.println("New file created!");//testing
} catch (IOException e) {
e.printStackTrace();
FacesMessage error = new FacesMessage("The files were not uploaded!");
FacesContext.getCurrentInstance().addMessage(null, error);
}
}
}
Just how can i print out the new destination and use this later on as currently it creates the new folder but does not select it to use
EDIT SOLVED THIS TOO :
NewDestination = "C:/Users/Richard/printing~subversion/fileupload/web/WEB-INF/uploaded/" + username;
Added the above code and now it all works

You have to actually call some method to create the directories. Just creating a file object will not create the corresponding file or directory on the file system.
You can use File#mkdirs() method to create the directory: -
theFile.mkdirs();
Difference between File#mkdir() and File#mkdirs() is that, the later will create any intermediate directory if it does not exist.

Use this code spinet for create intermediate folders if one doesn't exist while creating/editing file:
File outFile = new File("/dir1/dir2/dir3/test.file");
outFile.getParentFile().mkdirs();
outFile.createNewFile();

A nice Java 7+ answer from Benoit Blanchon can be found here:
With Java 7, you can use Files.createDirectories().
For instance:
Files.createDirectories(Paths.get("/path/to/directory"));

If you have a large hierarchy of stacked, non-existent directories, you must first call Files.createDirectories(..). For example, in Kotlin it may look like this:
fun File.createFileWithParentDirectories() {
if(this.exists())return
val parent = this.parentFile
if(!parent.exists()) Files.createDirectories(parent.toPath())
this.createNewFile()
}

Related

New file is getting created during FTP download

I'm trying to download a file from server using FTP, the Java code works if the file is available in remote server but if the specific file is not available in the remote server a new file is getting created with same file name in local. How can I avoid this?
and I'm trying to check the properties such as last modified time, file created time etc.., of the specific file before download, I used MLST but getting type casting issues..!!
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
public class FTPDownloadFileDemo {
public static void main(String[] args) {
String server = "www.myserver.com";
int port = 21;
String user = "user";
String pass = "pass";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "/test/video.mp4";
File downloadFile1 = new File("D:/Downloads/video.mp4");
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
System.out.println("File #1 has been downloaded successfully.");
}
outputStream2.close();
inputStream.close();
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
The retrieveFile() method always writes a local file, whether or not the remote file exists. Instead, you can use retrieveFileStream() and check the reply code.
A handy list of FTP reply codes is available from Wikipedia. If 550 is received, it means the file does not exist.
Finally, you need to use completePendingCommand() to complete the transaction and a FileOutputStream to write the file.
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile1);
int returnCode = ftpClient.getReplyCode();
if (inputStream == null || returnCode == 550) {
System.out.println("Remote file does not exist");
} else {
ftpClient.completePendingCommand();
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
OutputStream outputStream = new FileOutputStream(downloadFile1);
outputStream.write(buffer);
outputStream.close();
}
Your problem is that your Outputstream automatically creates the File, even if the stream is empty.
I would recommend you check first if the file exists on the server and based on that you don't even create the outputStream:
boolean checkFileExists(String filePath) throws IOException {
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile1);
returnCode = ftpClient.getReplyCode();
return inputStream == null || returnCode == 550;
}

Is it possible to retrieve a file from a remote path using java?

I've been tasked with a project to automate a process in which we extract a file from a WinSCP client daily. So far I've been able to automate the login and setup a recurring schedule for the code to run; however it seems I've hit a bump in the road. When I attempt to locate a file for retrieval nothing happens. This is because the file I wish to access is through a remote directory. I'm almost positive that the code I've written is bug free. I am just unsure if specify a certain path which java can locate the file. I have no idea how to tell the java code where to extract this file from. Any thoughts?
You can try and use the code below:
More details can be found here.
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
/**
* A program demonstrates how to upload files from local computer to a remote
* FTP server using Apache Commons Net API.
* #author www.codejava.net
*/
public class FTPDownloadFileDemo {
public static void main(String[] args) {
String server = "www.myserver.com";
int port = 21;
String user = "user";
String pass = "pass";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// APPROACH #1: using retrieveFile(String, OutputStream)
String remoteFile1 = "/test/video.mp4";
File downloadFile1 = new File("D:/Downloads/video.mp4");
OutputStream outputStream1 = new BufferedOutputStream(new FileOutputStream(downloadFile1));
boolean success = ftpClient.retrieveFile(remoteFile1, outputStream1);
outputStream1.close();
if (success) {
System.out.println("File #1 has been downloaded successfully.");
}
// APPROACH #2: using InputStream retrieveFileStream(String)
String remoteFile2 = "/test/song.mp3";
File downloadFile2 = new File("D:/Downloads/song.mp3");
OutputStream outputStream2 = new BufferedOutputStream(new FileOutputStream(downloadFile2));
InputStream inputStream = ftpClient.retrieveFileStream(remoteFile2);
byte[] bytesArray = new byte[4096];
int bytesRead = -1;
while ((bytesRead = inputStream.read(bytesArray)) != -1) {
outputStream2.write(bytesArray, 0, bytesRead);
}
success = ftpClient.completePendingCommand();
if (success) {
System.out.println("File #2 has been downloaded successfully.");
}
outputStream2.close();
inputStream.close();
} catch (IOException ex) {
System.out.println("Error: " + ex.getMessage());
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}

Set file path on FTPClient

i'm new to java programming and am using Apache commons net ftp to upload text files to my ftp server.
however, it seems that i can only upload the files on the same directory as my program .. when i set the file path to something like that : "C:\Users\Packard\Documents\ProjectsJava\FugeLessons\outputFile.txt" , it throws no errors, but when i check the ftp, there is nothing, like it has not been uploaded .
here is the code i'm using :
import org.apache.commons.net.ftp.FTPClient;
import java.io.FileInputStream;
import java.io.IOException;
public class ftp{
private final String host = "ftp.address.com";
private final String user = "user";
private final String pass = "pass";
public static void main(String[] args) {
ftp client = new ftp();
client.FtpUpload("C:\\Users\\Packard\\Documents\\ProjectsJava\\FugeLessons\\outputFile.txt");
}
public String FtpUpload(String filename){
FTPClient client = new FTPClient();
FileInputStream fis = null;
try {
client.connect(this.host);
client.login(this.user, this.pass);
fis = new FileInputStream(filename);
client.storeFile(filename, fis);
client.logout();
System.out.println("File " + filename + "\t uploaded successfully!");
} catch(IOException e){
error error = new error();
error.setVisible(true);
e.printStackTrace();
} finally {
try {
if ( fis != null) {
fis.close();
}
client.disconnect();
} catch(IOException e){
e.printStackTrace();
}
}
String ret = "success";
return ret;
}
}
what am i doing wrong ?
Thanks for your help!
You can use ftpClient method getReplyString() to get the error message. Below code can help.
boolean isSendSucces = ftpClient.storeFile(fileName, input );
if( isSendSuccess )
{
System.out.println("Sent File: " + fileName);
}
else
{
System.out.println("Problem is sending File: " + ftpClient.getReplyString());
}

How create progress bar while file transferring

import java.awt.Component;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.swing.JOptionPane;
import javax.swing.ProgressMonitorInputStream;
public class buckUpFile {
private Component parentComponent;
public void copyFile() {
File srcFolder = new File(
"C:\\Users\\ALLEN\\Workspace\\FINAL_LCTP_WORKBENCE_1.5");
File destFolder = new File(
"C:\\Data Programing\\COPY_OF_FINAL_LCTP_WORKBENCE_1.5");
if (!srcFolder.exists()) {
JOptionPane.showMessageDialog(null, "Directory does not exist.");
System.exit(0);
} else {
try {
copyFolder(srcFolder, destFolder);
} catch (IOException e) {
e.printStackTrace();
System.exit(0);
}
}
JOptionPane.showMessageDialog(null,
"Back up request has been completed");
}
public void copyFolder(File src, File dest) throws IOException {
if (src.isDirectory()) {
if (!dest.exists()) {
dest.mkdir();
}
String files[] = src.list();
for (String file : files) {
File srcFile = new File(src, file);
File destFile = new File(dest, file);
copyFolder(srcFile, destFile);
}
} else {
InputStream in = new BufferedInputStream(
new ProgressMonitorInputStream(parentComponent, "Reading "
+ src, new FileInputStream(src)));
OutputStream out = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
in.close();
out.close();
}
}
}
The codes i have above works just fine it allows me to copy the data of a file from one directory to another. My problem is, how can i create a progress bar? that i could attach to my codes to make my program more user friendly. I tried using ProgressMonitorInputStream but it looks like I'm in the wrong path.
I can think of two ways.
Swing Worker
Start by wrapping you copy code into a SwingWorker, using the setProgress method to update the progress and a property change listener to monitor changes to the progress property.
When the progress property changes, you would then update the UI.
This solution will require you to supply you own UI
Progress Monitor
Use a ProgressMonitorInputStream, which comes with it's own UI.
InputStream in = new BufferedInputStream(
new ProgressMonitorInputStream(
parentComponent,
"Reading " + fileName,
new FileInputStream(fileName)));
(Example stolen from Java Docs)
Here you can find same example. Making Progress With Swing's Progress Monitoring API.

Password protected zip file in java

I have created zip file using java as below snippet
import java.io.*;
import java.util.zip.*;
public class ZipCreateExample {
public static void main(String[] args) throws IOException {
System.out.print("Please enter file name to zip : ");
BufferedReader input = new BufferedReader
(new InputStreamReader(System.in));
String filesToZip = input.readLine();
File f = new File(filesToZip);
if(!f.exists()) {
System.out.println("File not found.");
System.exit(0);
}
System.out.print("Please enter zip file name : ");
String zipFileName = input.readLine();
if (!zipFileName.endsWith(".zip"))
zipFileName = zipFileName + ".zip";
byte[] buffer = new byte[18024];
try {
ZipOutputStream out = new ZipOutputStream
(new FileOutputStream(zipFileName));
out.setLevel(Deflater.DEFAULT_COMPRESSION);
FileInputStream in = new FileInputStream(filesToZip);
out.putNextEntry(new ZipEntry(filesToZip));
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.closeEntry();
in.close();
out.close();
} catch (IllegalArgumentException iae) {
iae.printStackTrace();
System.exit(0);
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
System.exit(0);
} catch (IOException ioe) {
ioe.printStackTrace();
System.exit(0);
}
}
}
Now I want when I click on the zip file it should prompt me to type password and then decompress the zip file.
Please any help,How should I go further?
Try the following code which is based on Zip4j:
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
public class Zipper
{
private String password;
private static final String EXTENSION = "zip";
public Zipper(String password)
{
this.password = password;
}
public void pack(String filePath) throws ZipException
{
ZipParameters zipParameters = new ZipParameters();
zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_ULTRA);
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
zipParameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
zipParameters.setPassword(password);
String baseFileName = FilenameUtils.getBaseName(filePath);
String destinationZipFilePath = baseFileName + "." + EXTENSION;
ZipFile zipFile = new ZipFile(destinationZipFilePath);
zipFile.addFile(new File(filePath), zipParameters);
}
public void unpack(String sourceZipFilePath, String extractedZipFilePath) throws ZipException
{
ZipFile zipFile = new ZipFile(sourceZipFilePath + "." + EXTENSION);
if (zipFile.isEncrypted())
{
zipFile.setPassword(password);
}
zipFile.extractAll(extractedZipFilePath);
}
}
FilenameUtils is from Apache Commons IO.
Example usage:
public static void main(String[] arguments) throws ZipException
{
Zipper zipper = new Zipper("password");
zipper.pack("encrypt-me.txt");
zipper.unpack("encrypt-me", "D:\\");
}
Standard Java API does not support password protected zip files. Fortunately good guys have already implemented such ability for us. Please take a look on this article that explains how to create password protected zip.
(The link was dead, latest archived version: https://web.archive.org/web/20161029174700/http://java.sys-con.com/node/1258827)
Sample code below will zip and password protect your file.
This REST service accepts bytes of the original file. It zips the byte array and password protects it. Then it sends bytes of password protected zipped file as response. The code is a sample of sending and receiving binary bytes to and from a REST service, and also of zipping a file with password protect. The bytes are zipped from stream, so no files are ever stored on the server.
Uses JAX-RS API using Jersey API in java
Client is using Jersey-client API.
Uses zip4j 1.3.2 open source library, and apache commons io.
#PUT
#Path("/bindata/protect/qparam")
#Consumes(MediaType.APPLICATION_OCTET_STREAM)
#Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response zipFileUsingPassProtect(byte[] fileBytes, #QueryParam(value = "pass") String pass,
#QueryParam(value = "inputFileName") String inputFileName) {
System.out.println("====2001==== Entering zipFileUsingPassProtect");
System.out.println("fileBytes size = " + fileBytes.length);
System.out.println("password = " + pass);
System.out.println("inputFileName = " + inputFileName);
byte b[] = null;
try {
b = zipFileProtected(fileBytes, inputFileName, pass);
} catch (IOException e) {
e.printStackTrace();
return Response.status(Status.INTERNAL_SERVER_ERROR).build();
}
System.out.println(" ");
System.out.println("++++++++++++++++++++++++++++++++");
System.out.println(" ");
return Response.ok(b, MediaType.APPLICATION_OCTET_STREAM)
.header("content-disposition", "attachment; filename = " + inputFileName + ".zip").build();
}
private byte[] zipFileProtected(byte[] fileBytes, String fileName, String pass) throws IOException {
ByteArrayInputStream inputByteStream = null;
ByteArrayOutputStream outputByteStream = null;
net.lingala.zip4j.io.ZipOutputStream outputZipStream = null;
try {
//write the zip bytes to a byte array
outputByteStream = new ByteArrayOutputStream();
outputZipStream = new net.lingala.zip4j.io.ZipOutputStream(outputByteStream);
//input byte stream to read the input bytes
inputByteStream = new ByteArrayInputStream(fileBytes);
//init the zip parameters
ZipParameters zipParams = new ZipParameters();
zipParams.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
zipParams.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
zipParams.setEncryptFiles(true);
zipParams.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
zipParams.setPassword(pass);
zipParams.setSourceExternalStream(true);
zipParams.setFileNameInZip(fileName);
//create zip entry
outputZipStream.putNextEntry(new File(fileName), zipParams);
IOUtils.copy(inputByteStream, outputZipStream);
outputZipStream.closeEntry();
//finish up
outputZipStream.finish();
IOUtils.closeQuietly(inputByteStream);
IOUtils.closeQuietly(outputByteStream);
IOUtils.closeQuietly(outputZipStream);
return outputByteStream.toByteArray();
} catch (ZipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
IOUtils.closeQuietly(inputByteStream);
IOUtils.closeQuietly(outputByteStream);
IOUtils.closeQuietly(outputZipStream);
}
return null;
}
Unit test below:
#Test
public void testPassProtectZip_with_params() {
byte[] inputBytes = null;
try {
inputBytes = FileUtils.readFileToByteArray(new File(inputFilePath));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("bytes read into array. size = " + inputBytes.length);
Client client = ClientBuilder.newClient();
WebTarget target = client.target("http://localhost:8080").path("filezip/services/zip/bindata/protect/qparam");
target = target.queryParam("pass", "mypass123");
target = target.queryParam("inputFileName", "any_name_here.pdf");
Invocation.Builder builder = target.request(MediaType.APPLICATION_OCTET_STREAM);
Response resp = builder.put(Entity.entity(inputBytes, MediaType.APPLICATION_OCTET_STREAM));
System.out.println("response = " + resp.getStatus());
Assert.assertEquals(Status.OK.getStatusCode(), resp.getStatus());
byte[] zipBytes = resp.readEntity(byte[].class);
try {
FileUtils.writeByteArrayToFile(new File(responseFilePathPasswordZipParam), zipBytes);
} catch (IOException e) {
e.printStackTrace();
}
}
Feel free to use and modify. Please let me know if you find any errors. Hope this helps.
Edit 1 - Using QueryParam but you may use HeaderParam for PUT instead to hide passwd from plain sight. Modify the test method accordingly.
Edit 2 - REST path is filezip/services/zip/bindata/protect/qparam
filezip is name of war. services is the url mapping in web.xml. zip is class level path annotation. bindata/protect/qparam is the method level path annotation.
In new version of Zip4j, class Zip4jConstants was removed. Use EncryptionMethod and AesKeyStrength class instead. Documentation : https://github.com/srikanth-lingala/zip4j
ZipParameters zipParameters = new ZipParameters();
zipParameters.setEncryptFiles(true);
zipParameters.setEncryptionMethod(EncryptionMethod.AES);
zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);
List<File> filesToAdd = Arrays.asList(
new File("somefile"),
new File("someotherfile")
);
ZipFile zipFile = new ZipFile("filename.zip", "password".toCharArray());
zipFile.addFiles(filesToAdd, zipParameters);
There is no default Java API to create a password protected file. There is another example about how to do it here.
Library Zip4J seems to be the preferred answer.
In case the privacy of the password is highly recommended, one might close a security gap in class ZipFile, which carries the password in plain text, even after the ZipFile is closed. Following method destroys the password.
public static void destroyZipPassword(ZipFile zip) throws DestroyFailedException
{
try
{
Field fdPwd = ZipFile.class.getDeclaredField("password");
fdPwd.setAccessible(true);
char[] password = (char[]) fdPwd.get(zip);
Arrays.fill(password, (char) 0);
}
catch (Exception e)
{
e.printStackTrace();
throw new DestroyFailedException(e.getMessage());
}
}

Categories