Java Code to Zip/FTP Directory in a UNIX Server - java

I want to write a couple of methods in a Java package, which would be deployed in a UNIX Server.
As of now, my code was for Windows Server, for which I used the following code to zip Directory.
public static final void zipDirectory(File fBatchDirectory, String batchName, String ondemandDocExtension) throws IOException
{
//Set zip file name
File zip = new File(fBatchDirectory + "\\" + StringUtils.replace(batchName,".ind", "") + ".zip");
//filter file
FileFilter filter = new FileFilter(ondemandDocExtension);
File[] files = fBatchDirectory.listFiles(filter);
if(files.length > 0)
{
ZipOutputStream zos = new ZipOutputStream( new FileOutputStream(zip) );
zip(files, fBatchDirectory, zos , ondemandDocExtension);
zos.close();
}
}
private static final void zip(File[] files, File base,ZipOutputStream zos , String docExtension) throws IOException
{
byte[] buffer = new byte[8192];
int read = 0;
for (int i = 0, n = files.length; i < n; i++)
{
//Add to zip only if its file
if (files[i].isFile())
{
FileInputStream in = new FileInputStream(files[i]);
ZipEntry entry = new ZipEntry(files[i].getPath().substring(base.getPath().length() + 1));
zos.putNextEntry(entry);
while (-1 != (read = in.read(buffer)))
{
zos.write(buffer, 0, read);
}
in.close();
}
}
}
I am confused as to how to replicate the same functionality to zip Directory in Java, for UNIX?
And then I want to FTP the files from a UNIX Serve to another UNIX Server.
Any pointers would be greatly appreciated.

At a first glance, the only problem I see is at this line:
File zip = new File(fBatchDirectory + "\\" + StringUtils.replace(batchName,".ind", "") + ".zip");
Because you are explicitly using the double backslash (\\) in your filename. If you change that for File.separator your code should work for both operating systems:
File zip = new File(fBatchDirectory + File.separator + StringUtils.replace(batchName,".ind", "") + ".zip");
For the FTP part of it, you can get down and dirty and use an FTP client or use a more high level library like Apache Commons VFS which, by the way, inspired the new IO FileSystem API in Java 7, but I don't now about any library implementing the FTP protocol with the new API at the moment.

Related

Create one Zip file using a set of pdf files

My app is a tender document system where each tender number has one or more pdf files attached.
application is done in java ee using struts and mysql.
in a database table the paths of each related pdf file for a tender number is stores.
I want to get all the pdf files and create a single ZIP file for each tender number so that user can download that zip file and have all the related documents in a single click.
I tried Google and found something called ZipOutputStream but i cannot understand how to use this in my application.
You're almost there... This is a small example of how to use ZipOutputStream... let's asume that you have a JAVA helper H that returns database records with pdf file paths (and related info):
FileOutputStream zipFile = new FileOutputStream(new File("xxx.zip"));
ZipOutputStream output = new ZipOutputStream(zipFile);
for (Record r : h.getPdfRecords()) {
ZipEntry zipEntry = new ZipEntry(r.getPdfName());
output.putNextEntry(zipEntry);
FileInputStream pdfFile = new FileInputStream(new File(r.getPath()));
IOUtils.copy(pdfFile, output); // this method belongs to apache IO Commons lib!
pdfFile.close();
output.closeEntry();
}
output.finish();
output.close();
Checkout this code, here you can easily create a zip file directory:
public class CreateZipFileDirectory {
public static void main(String args[])
{
try
{
String zipFile = "C:/FileIO/zipdemo.zip";
String sourceDirectory = "C:/examples";
//create byte buffer
byte[] buffer = new byte[1024];
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File dir = new File(sourceDirectory);
if(!dir.isDirectory())
{
System.out.println(sourceDirectory + " is not a directory");
}
else
{
File[] files = dir.listFiles();
for(int i=0; i < files.length ; i++)
{
System.out.println("Adding " + files[i].getName());
FileInputStream fin = new FileInputStream(files[i]);
zout.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while((length = fin.read(buffer)) > 0)
{
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
}
zout.close();
System.out.println("Zip file has been created!");
}
catch(IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
}

Having trouble copying directory from NFS mount in Java

I've been trying to copy a directory recursively from an NFS mount to the local file system in Java. I first tried using FileUtils in Apache Utils. Sadly, it didn't copy recursively (walking through sub-directories, etc.) so I had to go back to the drawing board. I heard that some of those operations are "finicky" when they are cross-device. I was then suggested to try and use linux commands, so I tried doing so:
Process process = new ProcessBuilder()
.command("cp -R " + source.getAbsolutePath() + " " + dest.getAbsolutePath())
.start();
process.waitFor();
That sadly threw a response of "no such file or directory", I slapped on some debug on there and tried again. Even though I got "no such file or directory", my debug stated that both the source and destination directories exist, as well as after checking manually if they exist.
Alright, so I decided to write my own implementation and oddly enough it worked. Sadly, I have little-to-no knowledge why this worked over FileUtils. Here is what I wrote:
private void copy(File source, File destination) throws IOException {
if (source.isDirectory()) {
if (!destination.exists()) {
destination.mkdir();
}
if (destination.isFile()) {
destination.delete();
destination.mkdir();
}
for (File src : source.listFiles()) {
File dest = new File(destination, src.getName());
copy(src, dest);
}
} else {
destination.createNewFile();
FileInputStream input = new FileInputStream(source);
FileOutputStream out = new FileOutputStream(destination);
byte[] buffer = new byte[2048];
int l;
while ((l = input.read(buffer)) > 0) {
out.write(buffer, 0, l);
}
input.close();
out.close();
}
}

Create zip file to local machine

I have a below code in which my zip file is getting created on the server machine, i want the zip file to be created in the local machine, below is my code, please check the below code and let me know if anybody has a solution for it .
<%!
public static void addToZipFile(String fileName, ZipOutputStream zos) throws FileNotFoundException, IOException {
System.out.println("Writing '" + fileName + "' to zip file");
File file = new File(fileName);
FileInputStream fis = new FileInputStream(file);
ZipEntry zipEntry = new ZipEntry(file.getName());
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
fis.close();
}
%>
<%
String imgID = request.getParameter("iID").toString();
String epsFile = request.getParameter("epsNm").toString();
String ZipFile = imgID + ".zip";
//FileOutputStream fos = new FileOutputStream("d:/" + ZipFile);
FileOutputStream fos = new FileOutputStream(ZipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
File temp = new File(imgID);
String absolutePath = temp.getAbsolutePath();
System.out.println("filepath" + absolutePath);
String relativeWebPath = "CoverCapPDF/"+ imgID;
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
System.out.println("absoluteDiskPath" + absoluteDiskPath);
String relativeWebPathEPS = "eps/"+ epsFile;
String absoluteDiskPathEPS = getServletContext().getRealPath(relativeWebPathEPS);
System.out.println("absoluteDiskPath" + absoluteDiskPathEPS);
String file1Name = absoluteDiskPath;
String file2Name = absoluteDiskPathEPS;
String file3Name = "file2.txt";
addToZipFile(file1Name, zos);
addToZipFile(file2Name, zos);
zos.close();
fos.close();
%>
please help me :)
I am assuming you are dealing with a web application which uses JSP (since the above syntax suggests the same). The answer then is you cannot.
What you can do is
Create the file at the server and ask the client to download refer here
Create an applet and the applet can have the zip code (though not recommended for security reasons)
First of all, you should not use a JSP for this, but a servlet. JSPs are view components, whose role is to generate HTML markup using the JSP EL, the JSTL and other custom tags, but no scriptlet.
Second: you're writing to a FileOutputStream. that obviously writes your zip entries to a file. You want to write your zip entries to the HTTP response. You should thus use the response output stream to write your zip entries.
To tell the browser that you're sending what should be saved as a zip file, use
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
(this should be called before sending anything to the response output stream)

How to create zip with lzma compression

I know how to create zip archive:
import java.io.*;
import java.util.zip.*;
public class ZipCreateExample{
public static void main(String[] args) throws Exception
// input file
FileInputStream in = new FileInputStream("F:/sometxt.txt");
// out put file
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("F:/tmp.zip"));
// name the file inside the zip file
out.putNextEntry(new ZipEntry("zippedjava.txt"));
// buffer size
byte[] b = new byte[1024];
int count;
while ((count = in.read(b)) > 0) {
System.out.println();
out.write(b, 0, count);
}
out.close();
in.close();
}
}
But I have no idea how to use lzma compression.
I found this project: https://github.com/jponge/lzma-java which creating compressed file but I don't know how I should combine it with my existing solution.
The latest version of Apache Commons Compress (1.6 released on 23-Oct-2013) supports LZMA compression.
Have a look at http://commons.apache.org/proper/commons-compress/examples.html, specially the one regarding .7z compressing/uncompressing.
Say for example you want to store an html page from an HTTP Response and you want to compress it:
SevenZOutputFile sevenZOutput = new SevenZOutputFile(new File("outFile.7z"));
File entryFile = new File(System.getProperty("java.io.tmpdir") + File.separator + "web.html");
SevenZArchiveEntry entry = sevenZOutput.createArchiveEntry(entryFile, "web.html");
sevenZOutput.putArchiveEntry(entry);
sevenZOutput.write(rawHtml.getBytes());
sevenZOutput.closeArchiveEntry();
sevenZOutput.close();
There is an example in the website you mentioned:
Adapted to your needs:
final File sourceFile = new File("F:/sometxt.txt");
final File compressed = File.createTempFile("lzma-java", "compressed");
final LzmaOutputStream compressedOut = new LzmaOutputStream.Builder(
new BufferedOutputStream(new FileOutputStream(compressed)))
.useMaximalDictionarySize()
.useEndMarkerMode(true)
.useBT4MatchFinder()
.build();
final InputStream sourceIn = new BufferedInputStream(new FileInputStream(sourceFile));
IOUtils.copy(sourceIn, compressedOut);
sourceIn.close();
compressedOut.close();
(I don't know if it works, it is just the usage of the library and your code snippet)
zip4jvm supports LZMA compression for zip archive.
ZipEntrySettings entrySettings = ZipEntrySettings.builder()
.compression(Compression.LZMA, CompressionLevel.NORMAL)
.lzmaEosMarker(true).build();
ZipSettings settings = ZipSettings.builder().entrySettingsProvider(fileName -> entrySettings).build();
Path file = Paths.get("F:/sometxt.txt");
Path zip = Paths.get("F:/tmp.zip");
ZipIt.zip(zip).settings(settings).add(file);

java.util.zip has problems with periods in filenames / directorynames?

I want to unzip an iPhone app .ipa file.
This is actually zip file that extracts normally.
But the actual app file in it is a folder with the ending .app ( as all mac applications are actually folders with the ending .app).
Now the period seems to be a problem for java.util.zip.
public static void main(String[] args) throws IOException {
ZipFile zipFile = new ZipFile("file.zip");
String path = "";
Enumeration files = zipFile.entries();
while (files.hasMoreElements()) {
ZipEntry entry = (ZipEntry) files.nextElement();
if (entry.isDirectory()) {
File file = new File(path + entry.getName());
file.mkdir();
System.out.println("Create dir " + entry.getName());
} else {
File f = new File(entry.getName());
FileOutputStream fos = new FileOutputStream(f); //EXception occurs here
InputStream is = zipFile.getInputStream(entry);
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = is.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
fos.close();
System.out.println("Create File " + entry.getName());
}
}
}
This is my output:
Exception in thread "main" java.io.FileNotFoundException: Payload/SMA Jobs.app/06-magnifying-glass.png (No such file or directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
at Main.main(Main.java:27)
enter code here
Anyone knows how to handle those periods?
First of all, you should use mkdirs(), not mkdir().
second, zip files don't always include all the directory entries (or have them in the right order). the best practice is to make the directories in both branches of the code, so add:
} else {
File f = new File(entry.getName());
f.getParent().mkdirs();
(you should add some checking to make sure getParent() is not null, etc).
I don't think the period is the problem. Look at the absolute path of the file you are trying to output and make sure it is pointing to the correct place.
if (entry.isDirectory()) {
File file = new File(path + entry.getName());
....
} else {
File f = new File(entry.getName());
....
While creating directory, file path passed is path + entry.getName()
but while creating file, file path passed is entry.getName()
After changing file path to path + entry.getName(), code works for period file names and normal file names. :)

Categories