UPDATE
For issue #2 regarding the folder, I just replaced ZipEntry ze = new ZipEntry(source + File.separator + file); with ZipEntry ze = new ZipEntry(file);.
Issue remains with WINZIP not able to open the zipped file while unzip can unzip the file. WINZIP's error is: Error: unable to seek to beginning of central directory.
ORIGINAL POST
I have the following code that I have gotten and slightly modified from one of the questions on SO. In my application, I set OUTPUT_ZIP_FILE to /var/tmp/test/test.zip and my source folder as /var/tmp/test.
I have two problems:
1- Winzip does not recognize the zip file while unix unzip does - Not sure if this is due to #2 below
2- when I use unzip to unzip the file, it unzips the whole directory hierarchy: It creates /var/tmp/test inside of /var/tmp/test leading to /var/tmp/test/var/tmp/test and then the files inside that... I only want to zip the files and not the hierarchy...
Any help would be much appreciated!
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFiles {
List<String> fileList;
String OUTPUT_ZIP_FILE;
String SOURCE_FOLDER;
ZipFiles() {
fileList = new ArrayList<String>();
}
public void zipIt(String ZipFiles) {
byte[] buffer = new byte[1024];
String source = "";
Boolean shouldZip = true;
try {
try {
// System.out.println("ZipFiles::zipIt::SOURCE_FOLDER::" +
// SOURCE_FOLDER);
source = SOURCE_FOLDER.substring(
SOURCE_FOLDER.lastIndexOf("\\") + 1,
SOURCE_FOLDER.length());
// System.out.println("ZipFiles::zipIt::source::" + source);
} catch (Exception e) {
source = SOURCE_FOLDER;
}
for (String file : this.fileList) {
if (file.endsWith("zip")) // This has already been zipped
{
shouldZip = false;
}
}
if (shouldZip) {
FileOutputStream fos = new FileOutputStream(ZipFiles);
ZipOutputStream zos = new ZipOutputStream(fos);
// System.out.println("Output to Zip : " + ZipFiles);
for (String file : this.fileList) {
// System.out.println("File Added : " + file);
ZipEntry ze = new ZipEntry(source + File.separator + 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();
// remember close it
zos.close();
}
// System.out.println("Folder successfully compressed");
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void generateFileList(File node) {
// add file only
if (node.isFile()) {
fileList.add(generateZipEntry(node.toString()));
}
if (node.isDirectory()) {
String[] subNote = node.list();
for (String filename : subNote) {
generateFileList(new File(node, filename));
}
}
}
private String generateZipEntry(String file) {
// System.out.println("ZipFiles::generateZipEntry::file::" + file);
return file.substring(SOURCE_FOLDER.length(), file.length());
}
}
As noted in the update to my question, for issue #2: just replaced ZipEntry ze = new ZipEntry(source + File.separator + file); with ZipEntry ze = new ZipEntry(file);
For issue #1 with winzip, the zip file I was testing was actually being downloaded via my webapp. Problem was in my groovy side of the code actually:
def download = {
def folder = params.folder
def file = new File( folder.toString())
response.setHeader "Content-disposition", "attachment; filename=${file.name}"
response.outputStream << file.text
response.outputStream.flush()
response.outputStream.close()
}
When I replaced outputStream <<file.text with outputStream << file.newInputStream() everything worked correctly.
As for Unix' unzip, I was testing directly on the created file instead of the downloaded file!!!
Related
I'm trying to create and add files to that directory. And below is my code, I'm able to create and add files to them, but at the end it is throwing me an exception.
My Code:
Unzip_Main.java
import java.io.File;
public class UnZip_Main {
public static void main(String[] args) {
String zipFilePath = "D:\\News\\Zip\\";
String destDirectory = "D:\\News\\Zip\\Result\\";
new File(destDirectory).mkdir();
UnZip unzipper = new UnZip();
File dir = new File(zipFilePath);
File[] files = dir.listFiles();
if (null != files) {
for (int fileIntList = 0; fileIntList < files.length; fileIntList++) {
String ss = files[fileIntList].toString();
if (null != ss && ss.length() > 0) {
System.out.println("unzip path is ");
try {
System.out.println("dest directry is " + destDirectory);
unzipper.unzip(zipFilePath + ss.substring(ss.lastIndexOf("\\") + 1, ss.length()),
destDirectory);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
}
Unzip.java
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnZip {
private static final int BUFFER_SIZE = 4096;
public void unzip(String zipFilePath, String destDirectory) throws IOException {
File destDir = new File(destDirectory);
if (!destDir.exists()) {
destDir.mkdir();
}
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
// if the entry is a file, extracts it
extractFile(zipIn, filePath, zipFilePath);
} else {
// if the entry is a directory, make the directory
File dir = new File(filePath);
dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
private void extractFile(ZipInputStream zipIn, String filePath, String zipFilePath) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath, true));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
File newName = new File(filePath);
String str = zipFilePath.substring(zipFilePath.lastIndexOf("\\") + 1, zipFilePath.lastIndexOf("."));
File zipPath = new File(filePath);
zipPath.mkdir();
File oldName = new File(zipPath.getParent() + "\\" + str + ".xml");
if (oldName.exists()) {
oldName.delete();
}
System.out.println("new name is " + newName + "and old name is " + oldName);
if (newName.renameTo(oldName)) {
System.out.println("Renamed");
} else {
System.out.println("Not Renamed");
}
}
}
My output:
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\If16c0c30613111e5850ddea403ecf0ba.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\If83120c05dd311e599a896be76e2f024.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\If8915610629d11e5b64da6abc0693b3d.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\If93445c0661f11e5839c9a236dd16599.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\If9bd10a061f411e5b445d6756f17230b.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\Ife581970612c11e5b64da6abc0693b3d.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\Ifed1c1f05f9a11e5bc448d3219668f6c.xml
Renamed
unzip path is
dest directry is D:\News\Zip\Result\
new name is D:\News\Zip\Result\content.xmland old name is D:\News\Zip\Result\Iff5aa9905d4011e5bb1df062954439f5.xml
Renamed
Exception at the end:
java.io.FileNotFoundException: D:\News\Zip\Result (Access is denied)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at UnZip.unzip(UnZip.java:17)
at UnZip_Main.main(UnZip_Main.java:19)
The files are created in correct folder, all of them are created, but still getting this exception, unable to know where I have gone wrong and how to fix it.
Another thing observed is if i change String destDirectory = "D:\\News\\Zip\\Result\\"; to String destDirectory = "D:\\News\\Zip\\";, and if there is any folder inside Zip path, i'm getting the same above result with exception, else it is not throwing any exception.
add a check for like this
if(files[fileIntList].isDirectory())
continue;
also you should change your file rename code it should be
oldName.renameTo(newName)
ideally you should remove new File(destDirectory).mkdir();
This line is causing the exception:
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
because you are giving it a directory ( D:\News\Zip\Result )
please make sure you are giving it a file path and not a directory path.
Try to put a breakpoint to check.
Get FileNotFoundException when initialising FileInputStream with File object
You can't open a directory as a file. Your FileInputStream is attempting to open D:\\News\\Zip\\Result\\ which is a directory.
im using this code it perfectly create zip files for example i have folder
sdcard/music and when i create xxx.zip file it creates .zip file includes music/songs and also some sub folders in it
but i want to exclude "music" the main Folder in the .zip file and want it to start directly including all songs and subfolders in it,how to do it
i use this way but it takes main folder name as well when zipping
public void unzipbutton(View v){ // button click
try {
FileOutputStream fos = new FileOutputStream("/mnt/sdcard/songs.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
addDirToZipArchive(zos, new File("/mnt/sdcard/music"), null);
zos.flush();
fos.flush();
zos.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void addDirToZipArchive(ZipOutputStream zos, File fileToZip, String parrentDirectoryName) throws Exception {
if (fileToZip == null || !fileToZip.exists()) {
return;
}
String zipEntryName = fileToZip.getName();
if (parrentDirectoryName!=null && !parrentDirectoryName.isEmpty()) {
zipEntryName = parrentDirectoryName + "/" + fileToZip.getName();
}
if (fileToZip.isDirectory()) {
System.out.println("+" + zipEntryName);
for (File file : fileToZip.listFiles()) {
addDirToZipArchive(zos, file, zipEntryName);
}
} else {
System.out.println(" " + zipEntryName);
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(fileToZip);
zos.putNextEntry(new ZipEntry(zipEntryName));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
}
anybody help on this,thanks
this has been so tricky till now no way works at the moments for me :/
In your ZipEntry check the full path of zipEntryName, it must be something like: "music/Pink/try.mp3" just invoke a substring in order to obtain as zipEntryName "Pink/try.mp3", your zip file will be the same "songs.zip" but inside of it you'll find the folder "Pink" instead the main folder "music/Pink..."
It worked for me.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am working on unzip the zip file which contains Images only here below my code is given.
public void unZipImages(String zipFile, String outputFolder) {
byte[] buffer = new byte[2048];
try {
// create output directory is not exists
File folder = new File(Environment.getExternalStorageDirectory()
+ "/final_unzip_data/" + AppConstants.ManufacturerCode
+ "/Catalog/" + ""); 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();
if (fileName.contains("\\")) {
fileName = fileName.replace("\\", "/");
}
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(); } }
But I don't know what the error is occurring to unzip the file some images are dropping. I have searched many types of codes for unzip but nothing worked.
This code has solved my problem
private void unzipImage(String zipFile, String extractFolder) {
try {
CreateDir();
int BUFFER = 4096;
File file = new File(zipFile);
ZipFile zip = new ZipFile(file);
String newPath = extractFolder;
new File(newPath).mkdir();
Enumeration zipFileEntries = zip.entries();
// Process each entry
while (zipFileEntries.hasMoreElements()) {
// grab a zip file entry
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
String currentEntry = entry.getName();
currentEntry = currentEntry.replace('\\', '/');
File destFile = new File(newPath, currentEntry);
// destFile = new File(newPath, destFile.getName());
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if (!entry.isDirectory()) {
BufferedInputStream is = new BufferedInputStream(
zip.getInputStream(entry));
int currentByte;
// establish buffer for writing file
byte data[] = new byte[BUFFER];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos,
BUFFER);
// read and write until last byte is encountered
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
is.close();
}
zip.close();
}
} catch (Exception e) {
Log.e("ERROR: ", "" + e.getMessage());
}
}
Just have a look at http://www.lingala.net/zip4j/download.php , this library file is quick and good .
And you have the short explanation of using the library here
FYI : Here is the another references .
And regarding your code , I have also tried this snippet in my project already but it was ignoring small images while unzipping , so i used the above library . Now i could get it re-solved .
Could anybody help me with my java zip extractor as stated in the title I keep getting java.io.FileNotFoundException on the folders with files in them
public void UnZip() {
try {
byte[] data = new byte[1000];
int byteRead;
BufferedOutputStream bout = null;
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(sourceFile)));
ZipEntry entry;
while ((entry = zin.getNextEntry()) != null) {
String filename = entry.getName();
File newfile = new File(Deobf2 + File.separator + filename);
System.out.println("file unzip : " + newfile.getAbsoluteFile());
new File(newfile.getParent()).mkdirs();
FileOutputStream fos = new FileOutputStream(newfile);
int len;
while ((len = zin.read(data)) > 0) {
fos.write(data, 0, len);
}
fos.close();
entry = zin.getNextEntry();
}
zin.closeEntry();
zin.close();
System.out.println("Done");
} catch (Exception e) {
e.printStackTrace();
}
}
error log
http://pastebin.com/crMKaa37
values
static String tempDir = System.getProperty("java.io.tmpdir");
public static File Deobf = new File(tempDir + "Deobf");
public static String Deobf2 = Deobf.toString();
entire code paste
http://pastebin.com/1vTfABR1
I have copy pasted same code and it is working fine. I think u dont have administrator permission on C drive. login As Administrator and run . it will work.
Access Denied Exception will come when u don have administrator level of permission on C drive.
The problem is Your doing
String Deobf2 = Deobf.toString();//this does not give the location of the file
use
file.getAbsolutePath();
in your case Deobf.getAbsolutePath();
instead. Check http://www.mkyong.com/java/how-to-get-the-filepath-of-a-file-in-java/
if you want to get the path only till the parent directory check this How to get absolute path of directory of a file?
Problem fixed changed some code
for anyone whos wants a copy of the working zip extraction code here you go http://pastebin.com/bXL8pUSg
The variable Deobf2 in the output of the zip
I am trying to implement program to zip and unzip a file. All I want to do is to zip a file (fileName.fileExtension) with name as fileName.zip and on unzipping change it again to fileName.fileExtension.
This is how I used to rename files or change its extension.
public static void modify(File file)
{
int index = file.getName().lastIndexOf(".");
//print filename
//System.out.println(file.getName().substring(0, index));
//print extension
//System.out.println(file.getName().substring(index));
String ext = file.getName().substring(index);
//use file.renameTo() to rename the file
file.renameTo(new File("Newname"+ext));
}
edit: John's method renames the file (keeping the extension). To change the extension do:
public static File changeExtension(File f, String newExtension) {
int i = f.getName().lastIndexOf('.');
String name = f.getName().substring(0,i);
return new File(f.getParent(), name + newExtension);
}
This changes only the last extension to a filename, i.e. the .gz part of archive.tar.gz. Therefore it works fine with Linux hidden files, for which the name starts with a .
This is quite safe because if getParent() returns null (i.e. in the event of the parent being the system root) it is "cast" to an empty String as the whole argument to the File constructor is evaluated first.
The only case where you will get a funny output is if you pass in a File representing the system root itself, in which case the null is prepended to the rest of the path string.
Try with:
File file = new File("fileName.zip"); // handler to your ZIP file
File file2 = new File("fileName.fileExtension"); // destination dir of your file
boolean success = file.renameTo(file2);
if (success) {
// File has been renamed
}
I would check, if the file has an extension before changing. The solution below works also with files without extension or multiple extensions
public File changeExtension(File file, String extension) {
String filename = file.getName();
if (filename.contains(".")) {
filename = filename.substring(0, filename.lastIndexOf('.'));
}
filename += "." + extension;
file.renameTo(new File(file.getParentFile(), filename));
return file;
}
#Test
public void test() {
assertThat(changeExtension(new File("C:/a/aaa.bbb.ccc"), "txt"),
is(new File("C:/a/aaa.bbb.txt")));
assertThat(changeExtension(new File("C:/a/test"), "txt"),
is(new File("C:/a/test.txt")));
}
By the same logic as mentioned #hsz, but instead simply use replacement:
File file = new File("fileName.fileExtension"); // creating object of File
String str = file.getPath().replace(".fileExtension", ".zip"); // replacing extension to another
file.renameTo(new File(str));
I want to avoid the new extension just happening to be in the path or filename itself. I like a combination of java.nio and apache StringFilenameUtils.
public void changeExtension(Path file, String extension) throws IOException {
String newFilename = FilenameUtils.removeExtension(file.toString()) + EXTENSION_SEPARATOR_STR + extension;
Files.move(file, Paths.get(newFilename, StandardCopyOption.REPLACE_EXISTING));
}
If you are using Kotlin you can use from this property of your file object:
file.nameWithoutExtension + "extension"
FilenameUtils.getFullPathNoEndSeparator(doc.getDocLoc()) + "/" +
FilenameUtils.getBaseName(doc.getDocLoc()) + ".xml"
My firend was working on a zipper in Java some 4 months back, I got this code from him.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipFiles {
List<String> filesListInDir = new ArrayList<String>();
public static void main(String[] args) {
File file = new File("/Users/pankaj/sitemap.xml");
String zipFileName = "/Users/pankaj/sitemap.zip";
File dir = new File("/Users/pankaj/tmp");
String zipDirName = "/Users/pankaj/tmp.zip";
zipSingleFile(file, zipFileName);
ZipFiles zipFiles = new ZipFiles();
zipFiles.zipDirectory(dir, zipDirName);
}
/**
* This method zips the directory
* #param dir
* #param zipDirName
*/
private void zipDirectory(File dir, String zipDirName) {
try {
populateFilesList(dir);
//now zip files one by one
//create ZipOutputStream to write to the zip file
FileOutputStream fos = new FileOutputStream(zipDirName);
ZipOutputStream zos = new ZipOutputStream(fos);
for(String filePath : filesListInDir){
System.out.println("Zipping "+filePath);
//for ZipEntry we need to keep only relative file path, so we used substring on absolute path
ZipEntry ze = new ZipEntry(filePath.substring(dir.getAbsolutePath().length()+1, filePath.length()));
zos.putNextEntry(ze);
//read the file and write to ZipOutputStream
FileInputStream fis = new FileInputStream(filePath);
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
fis.close();
}
zos.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* This method populates all the files in a directory to a List
* #param dir
* #throws IOException
*/
private void populateFilesList(File dir) throws IOException {
File[] files = dir.listFiles();
for(File file : files){
if(file.isFile())
filesListInDir.add(file.getAbsolutePath());
else
populateFilesList(file);
}
}
/**
* This method compresses the single file to zip format
* #param file
* #param zipFileName
*/
private static void zipSingleFile(File file, String zipFileName) {
try {
//create ZipOutputStream to write to the zip file
FileOutputStream fos = new FileOutputStream(zipFileName);
ZipOutputStream zos = new ZipOutputStream(fos);
//add a new Zip Entry to the ZipOutputStream
ZipEntry ze = new ZipEntry(file.getName());
zos.putNextEntry(ze);
//read the file and write to ZipOutputStream
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
//Close the zip entry to write to zip file
zos.closeEntry();
//Close resources
zos.close();
fis.close();
fos.close();
System.out.println(file.getCanonicalPath()+" is zipped to "+zipFileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
I haven't tried it personally, but he and also some of my other friends told me that it works.