i'm using the following code from the web
File dir = new File(dest.getAbsolutePath(), archiveName);
// create output directory if it doesn't exist
if (!dir.exists()) {
dir.mkdirs();
}
System.err.println(pArchivePath);
ZipFile zipFile = null;
try {
zipFile = new ZipFile(pArchivePath);
Enumeration<?> enu = zipFile.entries();
while (enu.hasMoreElements()) {
ZipEntry zipEntry = (ZipEntry) enu.nextElement();
String name = zipEntry.getName();
long size = zipEntry.getSize();
long compressedSize = zipEntry.getCompressedSize();
System.out.printf("name: %-20s | size: %6d | compressed size: %6d\n",
name, size, compressedSize);
File file = new File(name);
if (name.endsWith("/")) {
System.err.println("make dir " + name);
file.mkdirs();
continue;
}
File parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
InputStream is = zipFile.getInputStream(zipEntry);
FileOutputStream fos = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int length;
while ((length = is.read(bytes)) >= 0) {
fos.write(bytes, 0, length);
}
is.close();
fos.close();
}
zipFile.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (zipFile != null) {
try {
zipFile.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
to unzip an archive. It's packed with 7zip or Winrar as an .zip archive but renamed to .qtz (but i don't thing this causes the problem..)
So if i run the code to unzip my archive everything works fine: i get the output on sysout/err listing all files and also no exception occurs, but if i look in the destination directory ... it's empty - just the root folder exists.
I also used
Runtime.getRuntime().exec(String.format("unzip %s -d %s", pArchivePath, dest.getPath()));
but I can't use this anymore 'cause a new process is started and I'm continuing working on the archive right after the unzip process in the java code.
Well the question is.. why doesn't this peace of code work? There a lot of similar examples but none of them worked for me.
br, Philipp
EDIT: The following solved my Problem
File file = new File(dir.getParent(), name);
So i didn't set the right parent path for this file.
The below fragment in your code:
File parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
where does this create the parent directories? Because I tried your code and it's not creating in the destination directory but rather in my Eclipse's project directory. Looking at your code, the destination directory is nowhere used, right?
The code actually extracts the contents of the zip file but not where I expected it.
I am thinking because I don't see you doing something like this:
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipPath+ "Zip.zip"));
out.putNextEntry(new ZipEntry("Results.csv"));
I am still working on it but I think that the problem because that makes the file inside of the zip
Also you should probably use the ZipOutputStream to write; like
out.write(bytes, 0, length);
Related
So iam working on a project where i get to a point when i need to zip multiple folders (4folders to be specific) and one file in one output.zip file using java
So is there anyway for me to do it and by the way putting all the folders and file in one directory and then zipping it doesn't give the same result in other words the folders have to be in root level of the zip file
There are several solutions.
This one for example:
public static void zipDirectory(ZipOutputStream zos, File fileToZip, String parentDirectoryName) throws Exception
{
if (fileToZip == null || !fileToZip.exists())
{
return;
}
String zipEntryName = fileToZip.getName();
if (parentDirectoryName!=null && !parentDirectoryName.isEmpty())
{
zipEntryName = parentDirectoryName + "/" + fileToZip.getName();
}
// If we are dealing with a directory:
if (fileToZip.isDirectory())
{
System.out.println("+" + zipEntryName);
if(parentDirectoryName == null) // if parentDirectory is null, that means it's the first iteration of the recursion, so we do not include the first container folder
{
zipEntryName = "";
}
for (File file : fileToZip.listFiles()) // we iterate over all the folders/files and archive them by keeping the structure too.
{
zipDirectory(zos, file, zipEntryName);
}
} else // If we are dealing with a file, then we zip it directly
{
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();
}
}
then you could use this function like this:
try
{
File directoryToBeZipped = new File("C:\\New\\test");
FileOutputStream fos = new FileOutputStream("C:\\New\\test\\archive.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
zipDirectory(zos, directoryToBeZipped, null);
zos.flush();
fos.flush();
zos.close();
fos.close();
} catch (Exception e)
{
e.printStackTrace();
}
Or you could use the ZeroTurnAround ZIP Library. And do this in one line:
ZipUtil.pack(new File("D:\\sourceFolder\\"), new File("D:\\generatedZipFile.zip"));
Dead easy way (though you'll get warnings about proprietary classes)
final String[] ARGS = { "-cfM", "x.zip", "folder1", "folder2", "folder3", "folder4", "file.txt" };
sun.tools.jar.Main.main(ARGS);
It might be worth getting a similar thing that won't give you warnings
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.
I have a directory where I programmatically (in Java) do recursive unzipping (which seems to work), but in the end I'm left with a directory that has a lot of subdirectories and files. Every time I run this method I want to start with a clean slate, so I always delete the folder and its left-over files and subdirectories present in the temp directory.
root = new File(System.getProperty("java.io.tmpdir")+ File.separator + "ProductionTXOnlineCompletionDataPreProcessorRoot");
if(root.exists()){
try {
FileUtils.deleteDirectory(root);
} catch (IOException e) {
e.printStackTrace();
}
}
if(root.mkdir()){
rawFile = createRawDataFile();
}
I'm getting a really strange error from FileUtils.deleteDirectory though.
14:55:27,214 ERROR [stderr] (Thread-3 (HornetQ-client-global-threads-2098205981)) java.io.IOException: Unable to delete directory C:\Users\Admin\AppData\Local\Temp\ProductionTXOnlineCompletionDataPreProcessorRoot\ProductionTXOnlineCompletionDataPreProcessor8718674704286818303.
It seems to think that I have a period at the end of my directory (It doesn't, so it's no surprise that it can't delete it). Sometimes, this error appears on folders in the subdirectory. Has anyone seen this before?
I'm using the Commons IO 2.4 jar.
EDIT I've confirmed that the directories do not have periods, so unless they're invisible, I don't know why the method would think that there are periods. And the File's path that I give the method is set right before feeding it as an argument, and as anyone can see - it doesn't have a period at the end.
I'm running the program on Windows 7.
EDIT This is the code I used for recursively unzipping:
private void extractFolder(String zipFile) throws IOException
{
int BUFFER = 2048;
File file = new File(zipFile);
ZipFile zip = null;
String newPath = zipFile.substring(0, zipFile.length() - 4);
BufferedOutputStream dest = null;
BufferedInputStream is = null;
try{
zip = new ZipFile(zipFile);
Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
while (zipFileEntries.hasMoreElements())
{
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
String currentEntry = entry.getName();
File destFile = new File(newPath, currentEntry);
File destinationParent = destFile.getParentFile();
destinationParent.mkdirs();
if (!entry.isDirectory())
{
is = new BufferedInputStream(zip
.getInputStream(entry));
int currentByte;
byte data[] = new byte[BUFFER];
FileOutputStream fos = new FileOutputStream(destFile);
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();
}
if (currentEntry.endsWith(".zip")){
// found a zip file, try to open
extractFolder(destFile.getAbsolutePath());
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(dest!=null) {dest.close();}
if(is!=null) {is.close();}
zip.close();
}
}
I put the original zip into the root directory, and recursively unzip from there.
This is the relevant code showing that:
downloadInputStreamToFileInRootDir(in, rawFile);
try {
extractFolder(rawFile.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}catch (Exception e){
}
I just noticed that I use rawFile.getCanonicalPath() (rawFile is set in the first code excerpt) as the argument for extractFolder initially and then switch to destFile.getAbsolutePath() ... Maybe that has something to do with it. The problem with testing this is that the issue isn't deterministic. It sometimes happens and sometimes not.
The period is part of the error message. It's not trying to delete a file path with a period at the end. See the FileUtils source:
if (!directory.delete()) {
final String message =
"Unable to delete directory " + directory + ".";
throw new IOException(message);
}
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
Say I have a zip file MyZipFile.zip which contains (1) a file MyFile.txt and (2) a folder MyFolder which contains a file MyFileInMyFolder.txt, i.e. something as follows:
MyZipFile.zip
|-> MyFile.txt
|-> MyFolder
|-> MyFileInMyFolder.txt
I want to decompress this zip archive. The most common code sample I have been able to find searching online uses the ZipInputStream class somewhat like the code pasted at the bottom of this question. The problem with this however, using the example above, is that it will create MyFolder but will not decompress the contents of MyFolder. Anyone know whether it is possible to decompress the contents of a folder in a zip archive using ZipInputStream or by any other means?
public static boolean unzip(File sourceZipFile, File targetFolder)
{
// pre-stuff
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(sourceZipFile));
ZipEntry zipEntry = null;
while ((zipEntry = zipInputStream.getNextEntry()) != null)
{
File zipEntryFile = new File(targetFolder, zipEntry.getName());
if (zipEntry.isDirectory())
{
if (!zipEntryFile.exists() && !zipEntryFile.mkdirs())
return false;
}
else
{
FileOutputStream fileOutputStream = new FileOutputStream(zipEntryFile);
byte buffer[] = new byte[1024];
int count;
while ((count = zipInputStream.read(buffer, 0, buffer.length)) != -1)
fileOutputStream.write(buffer, 0, count);
fileOutputStream.flush();
fileOutputStream.close();
zipInputStream.closeEntry();
}
}
zipInputStream.close();
// post-stuff
}
Try this:
ZipInputStream zis = null;
try {
zis = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
// Create a file on HDD in the destinationPath directory
// destinationPath is a "root" folder, where you want to extract your ZIP file
File entryFile = new File(destinationPath, entry.getName());
if (entry.isDirectory()) {
if (entryFile.exists()) {
logger.log(Level.WARNING, "Directory {0} already exists!", entryFile);
} else {
entryFile.mkdirs();
}
} else {
// Make sure all folders exists (they should, but the safer, the better ;-))
if (entryFile.getParentFile() != null && !entryFile.getParentFile().exists()) {
entryFile.getParentFile().mkdirs();
}
// Create file on disk...
if (!entryFile.exists()) {
entryFile.createNewFile();
}
// and rewrite data from stream
OutputStream os = null;
try {
os = new FileOutputStream(entryFile);
IOUtils.copy(zis, os);
} finally {
IOUtils.closeQuietly(os);
}
}
}
} finally {
IOUtils.closeQuietly(zis);
}
Note, that it uses Apache Commons IO to handle stream copying / closing.