If My Application wants to zip the Resultant files(group of Files) using java in a dynamic way, what are the available options in Java?
When i Browsed I have got java.util.zip package to use, but is there any other way where I can use it to implement?
public class FolderZiper {
public static void main(String[] a) throws Exception {
zipFolder("c:\\a", "c:\\a.zip");
}
static public void zipFolder(String srcFolder, String destZipFile) throws Exception {
ZipOutputStream zip = null;
FileOutputStream fileWriter = null;
fileWriter = new FileOutputStream(destZipFile);
zip = new ZipOutputStream(fileWriter);
addFolderToZip("", srcFolder, zip);
zip.flush();
zip.close();
}
static private void addFileToZip(String path, String srcFile, ZipOutputStream zip)
throws Exception {
File folder = new File(srcFile);
if (folder.isDirectory()) {
addFolderToZip(path, srcFile, zip);
} else {
byte[] buf = new byte[1024];
int len;
FileInputStream in = new FileInputStream(srcFile);
zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
}
}
static private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip)
throws Exception {
File folder = new File(srcFolder);
for (String fileName : folder.list()) {
if (path.equals("")) {
addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
} else {
addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
}
}
}
}
The original Java implementation is known to have some bugs related to files encoding. For example it can't properly handle filenames with umlauts.
TrueZIP is an alternative that we've used in our project: https://truezip.dev.java.net/
Check the documentation on the site.
You can use ZIP file handling library that comes with JDK
Also this tutorials might be helpful.
Java have a java.util.zip.ZipInputStream and along with this you can use ZipEntry ... Something like
public static void unZipIt(String zipFile, String outputFolder){
File folder = new File(zipFile);
List<String> files = listFilesForFolder(folder);
System.out.println("Size " + files.size());
byte[] buffer = new byte[1024];
try{
Iterator<String> iter = files.iterator();
while(iter.hasNext()){
String file = iter.next();
System.out.println("file name " + file);
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
ZipEntry ze = zis.getNextEntry();
while(ze!=null){
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
System.out.println("file unzip : "+ newFile.getAbsoluteFile());
new File(newFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
System.out.println("Done");
}
}catch(IOException ex){
ex.printStackTrace();
}
}
Related
I need to zip a 30MB file into different zip files which have a limit of 5MB per zip file.
My work will stop to zip after the size is larger than the limit now. I referenced and tried some examples but made me feel confused.
Please give me suggestions. Thank you.
public static void zipDirectory(File dir, File zipFile, boolean contentOnly)
throws IOException {
synchronized (syncObj) {
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
if (contentOnly)
zipSubDirectory("", dir, zout);
else
zipSubDirectory(dir.getName() + "/", dir, zout);
zout.close();
}
}
private static void zipSubDirectory(String basePath, File dir,
ZipOutputStream zout) throws IOException {
synchronized (syncObj) {
byte[] buffer = new byte[4096];
final long MAX_ZIP_SIZE = 5000000;
long currentSize = 0;
int zipSplitCount = 0;
ZipEntry zipEntry;
FileInputStream entryFile;
File[] files = dir.listFiles();
for (File file : files) {
zipEntry = new ZipEntry(basePath + file.getName());
if (file.isDirectory()) {
String path = basePath + file.getName() + "/";
zout.putNextEntry(new ZipEntry(path));
zipSubDirectory(path, file, zout);
zout.closeEntry();
} else {
if (currentSize >= MAX_ZIP_SIZE) {
zipSplitCount++;
zout.close();
zout = new ZipOutputStream(new FileOutputStream(file.getName().replace(".zip", ".zip." + zipSplitCount)));
currentSize = 0;
}
zout.putNextEntry(zipEntry);
FileInputStream fin = new FileInputStream(file);
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
zout.closeEntry();
fin.close();
}
currentSize += zipEntry.getCompressedSize();
}
}
}
I have this updater class that updates my program by unzipping a zip file. It works good except when I add in a folder for it to extract.. I have included the 3 methods that I use to accomplish this but the problem must lie in the unzip() method.
Once it prints Extracting: New folder/TEST2.txt it makes the error posted below. I have tried making the folder without spaces and it throws the same error. The contests of the zip file are just 2 text files and a folder.
Structure of zip:
New Folder >Test2.txt
Test1.txt
Errors:
java.io.IOException: The system cannot find the path specified at
java.io.WinNTFileSystem.createFileExclusively(Native Method) at
java.io.File.createNewFile(Unknown Source) at
update.Main_Gui.unzip(Main_Gui.java:244) at
update.Main_Gui.access$3(Main_Gui.java:230) at
update.Main_Gui$3.run(Main_Gui.java:108) at
java.lang.Thread.run(Unknown Source)
Code:
private void copyFiles(File f, String dir) throws IOException {
File[] files = f.listFiles();
for (File ff : files) {
if (ff.isDirectory()) {
new File(dir + "/" + ff.getName()).mkdir();
copyFiles(ff, dir + "/" + ff.getName());
} else {
copy(ff.getAbsolutePath(), dir + "/" + ff.getName());
}
}
}
public void copy(String srFile, String dtFile)
throws FileNotFoundException, IOException {
File f1 = new File(srFile);
File f2 = new File(dtFile);
InputStream in = new FileInputStream(f1);
OutputStream out = new FileOutputStream(f2);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
private void unzip() throws IOException {
int BUFFER = 2048;
BufferedOutputStream dest = null;
BufferedInputStream is = null;
ZipEntry entry;
ZipFile zipfile = new ZipFile("update.zip");
Enumeration e = zipfile.entries();
(new File(root)).mkdir();
while (e.hasMoreElements()) {
entry = (ZipEntry) e.nextElement();
outText.setText(outText.getText() + "\nExtracting: " + entry);
if (entry.isDirectory())
(new File(root + entry.getName())).mkdir();
else {
(new File(root + entry.getName())).createNewFile();
is = new BufferedInputStream(zipfile.getInputStream(entry));
int count;
byte data[] = new byte[BUFFER];
FileOutputStream fos = new FileOutputStream(root
+ entry.getName());
dest = new BufferedOutputStream(fos, BUFFER);
while ((count = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
//zipfile.close();
dest.flush();
dest.close();
is.close();
}
}
}
I'm having an issue zipping up folders.
I.e. I'll have a folder like this
C:\Lazy\Test
containing files File1.cpp, File2.hpp,.. etc
The zipped up folder looks like C:\Lazy\Test.zip -> Lazy\Test which contains all the cpp and hpp files.
I want to remove the extra subfolders (Lazy\Test) that get created. Why is this happening?
In other words, the zipped up files are not directly underneath the zip file, I have to navigate two more folders to get to them.
Where can I find this issue in the code?
private void zipDirectory() {
File lazyDirectory = new File(defaultSaveLocation);
File[] files = lazyDirectory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
System.out.println("Zipping up " + file);
zipContents(file);
}
}
}
public static void addToZip(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(fileName);
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();
}
public static void zipContents(File dirToZip) {
List<File> fileList = new ArrayList<File>();
File[] filesToZip = dirToZip.listFiles();
for (File zipThis : filesToZip) {
String ext = "";
int i = zipThis.toString().lastIndexOf('.');
if (i > 0) {
ext = zipThis.toString().substring(i+1);
}
if(ext.matches("cpp|bem|gz|h|hpp|pl|pln|ppcout|vec|xml|csv")){
fileList.add(zipThis);
}
}
try {
FileOutputStream fos = new FileOutputStream(dirToZip.getName() + ".zip");
ZipOutputStream zos = new ZipOutputStream(fos);
for (File file : fileList) {
addToZip(file.toString(), zos);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Change the addToZip file to take File object. Use it to open the file stream, but only use File#getName to create the ZipEntry, as follows...
public static void addToZip(File file, ZipOutputStream zos) throws FileNotFoundException, IOException {
System.out.println("Writing '" + fileName + "' to zip file");
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();
}
I'm trying to extract a zip file to another location, and I'm getting denied access error..
CODE:
package org.spoutcraft.launcher;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnZip
{
List<String> fileList;
private static final String INPUT_ZIP_FILE = "C:\\Level Up! Games" + File.separator + "Perfect World" + File.separator + "Updates" + File.separator + "Launcher.zip";
private static final String OUTPUT_FOLDER = "C:\\Level Up! Games" + File.separator + "Perfect World";
public static void main( String[] args )
{
UnZip unZip = new UnZip();
unZip.unZipIt(INPUT_ZIP_FILE,OUTPUT_FOLDER);
}
/**
* Unzip it
* #param zipFile input zip file
* #param output zip file output folder
*/
public void unZipIt(String zipFile, String outputFolder)
{
byte[] buffer = new byte[1024];
try
{
//create output directory is not exists
File folder = new File(OUTPUT_FOLDER);
if(!folder.exists())
{
folder.mkdir();
}
//get the zip file content
ZipInputStream zis = new ZipInputStream(new FileInputStream(zipFile));
//get the zipped file list entry
ZipEntry ze = zis.getNextEntry();
while(ze!=null)
{
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator + fileName);
System.out.println("file unzip : "+ newFile.getAbsoluteFile());
//create all non exists folders
//else you will hit FileNotFoundException for compressed folder
new File(newFile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0)
{
fos.write(buffer, 0, len);
}
fos.close();
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
System.out.println("Done");
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
In the main class i've used this code:
After download the zip file:
try {
UnZip.main(null);
And im getting this error:
file unzip : C:\Level Up! Games\Perfect World\config
java.io.FileNotFoundException: C:\Level Up! Games\Perfect World\config (Acesso negado)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at org.spoutcraft.launcher.UnZip.unZipIt(UnZip.java:57)
at org.spoutcraft.launcher.UnZip.main(UnZip.java:20)
Can someone help me?
I assume that in line
FileOutputStream fos = new FileOutputStream(newFile);
you are creating stream to entry representing directory, where you should only create streams to files.
Try changing your loop to
while (ze != null) {
String fileName = ze.getName();
File newFile = new File(outputFolder + File.separator
+ fileName);
System.out.println("file unzip : " + newFile);
// create all non exists folders
// else you will hit FileNotFoundException for compressed folder
if (ze.isDirectory()) {
newFile.mkdirs();
} else {
FileOutputStream fos = new FileOutputStream(newFile);
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
}
ze = zis.getNextEntry();
}
This question already has answers here:
directories in a zip file when using java.util.zip.ZipOutputStream
(6 answers)
Closed 9 years ago.
My task requires me to save a file directory into a zip folder. My only problem is I need to keep the sub-folders as folders from the main Directory. The file system will look something like
C\\Friends
C:\\Friends\\Person1\\Information.txt
C:\\Friends\\Person2\\Information.txt
C:\\Friends\\Person3\\Information.txt
.
.
.
Right now I am able to write just the txt files inside of my zip folder, but in my zip folder I need to keep that folder structure. I know the way my code is right now will tell me the file I'm trying to write is closed(No access). My Functions thus far:
private String userDirectroy = "" //This is set earlier in the program
public void exportFriends(String pathToFile)
{
String source = pathToFile + ".zip";
try
{
String sourceDir = userDirectory;
String zipFile = source;
try
{
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File fileSource = new File(sourceDir);
addDirectory(zout, fileSource);
zout.close();
System.out.println("Zip file has been created!");
}
catch(Exception e)
{
}
}
catch(Exception e)
{
System.err.println("First Function: " + e);
}
}
private static void addDirectory(ZipOutputStream zout, File fileSource) {
File[] files = fileSource.listFiles();
System.out.println("Adding directory " + fileSource.getName());
for(int i=0; i < files.length; i++)
{
if(files[i].isDirectory())
{
try
{
byte[] buffer = new byte[1024];
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);
}
}
catch(Exception e)
{
System.err.println(e);
}
addDirectory(zout, files[i]);
continue;
}
try
{
System.out.println("Adding file " + files[i].getName());
//create byte buffer
byte[] buffer = new byte[1024];
//create object of FileInputStream
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();
//close the InputStream
fin.close();
}
catch(IOException ioe)
{
System.out.println("IOException :" + ioe);
}
}
}
Any help would be much appreciated. Thank You
For each folder, you need to add a empty ZipEntry of the path.
For each file, you need to supply both the path and file name. This will require you to know the part of the path to strip off, this would be everything after the start directory
Expanded concept
So, from your example, if the start directory is C:\Friends, then the entry for C:\Friends\Person1\Information.txt should look like Person1\Information.txt
public void exportFriends(String pathToFile) {
String source = pathToFile + ".zip";
try {
String sourceDir = "C:/Friends";
String zipFile = source;
try {
FileOutputStream fout = new FileOutputStream(zipFile);
ZipOutputStream zout = new ZipOutputStream(fout);
File fileSource = new File(sourceDir);
addDirectory(zout, sourceDir, fileSource);
zout.close();
System.out.println("Zip file has been created!");
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getRelativePath(String sourceDir, File file) {
// Trim off the start of source dir path...
String path = file.getPath().substring(sourceDir.length());
if (path.startsWith(File.pathSeparator)) {
path = path.substring(1);
}
return path;
}
private static void addDirectory(ZipOutputStream zout, String sourceDir, File fileSource) throws IOException {
if (fileSource.isDirectory()) {
// Add the directory to the zip entry...
String path = getRelativePath(sourceDir, fileSource);
if (path.trim().length() > 0) {
ZipEntry ze = new ZipEntry(getRelativePath(sourceDir, fileSource));
zout.putNextEntry(ze);
zout.closeEntry();
}
File[] files = fileSource.listFiles();
System.out.println("Adding directory " + fileSource.getName());
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
addDirectory(zout, sourceDir, files[i]);
} else {
System.out.println("Adding file " + files[i].getName());
//create byte buffer
byte[] buffer = new byte[1024];
//create object of FileInputStream
FileInputStream fin = new FileInputStream(files[i]);
zout.putNextEntry(new ZipEntry(getRelativePath(sourceDir, files[i])));
int length;
while ((length = fin.read(buffer)) > 0) {
zout.write(buffer, 0, length);
}
zout.closeEntry();
//close the InputStream
fin.close();
}
}
}
}