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.
Related
In my program I suppose to copy a directory to another directory with java. I did it but the only problem is that for the directories that are inside the source directory get copied but not the file inside them. Why?
This is the assigment:
Ask the user for the source directory and a destination. The source is the directory to be copied; the destination is the directory that will be the parent of the new copy.
First your program should make a new directory in the new location with the same name as the source directory. (You may need to do something special for root directories if you are copying an entire disk. A root directory has no parent directory, and often, no name.)
Then your program should create an array with File class objects for each item in the contents of the source directory, similar to what was done in DirectoryListDemo.
Next , it should iterate the array, and for each item in the array,
if it is a file, copy the file to the new directory using the copyFile() method taken from CopyFileDemoE.
if it is a directory, recursively call this method to copy the directory and all of its contents.
Here is the code:
package com.company;
import java.io.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws Exception {
Scanner src = new Scanner(System.in);
System.out.println("Enter name of source directory to copy from: ");
String sourceFile= src.nextLine();
System.out.println("Enter name of destination directory to copy the files into: ");
String destinationFile = (src.nextLine()+"/"+sourceFile);
isDirFile(sourceFile, destinationFile);
}
public static void isDirFile(String source, String dest) throws Exception{
File sourceFile = new File ("C:/"+source);
File dirFile = new File (dest, new File(source).getName());
dirFile.mkdirs();
File[] entries;
if (dirFile.exists()){
if (sourceFile.isDirectory()){
entries = sourceFile.listFiles();
assert entries != null;
for (File entry:entries){
if(entry.isFile()){
copyFile(entry.getAbsolutePath(),dest);
}
else{
isDirFile(entry.getAbsolutePath(),dest);
}
}
}
}
else{
System.out.println("File does not exist");
}
}
public static void copyFile(String source, String destination) throws Exception{
File sourceFile;
File destFile;
FileInputStream sourceStream;
FileOutputStream destSteam;
BufferedInputStream bufferedSource = null;
BufferedOutputStream bufferedDestination = null;
try{
sourceFile = new File(source);
destFile = new File (destination, new File(source).getName());
sourceStream = new FileInputStream(sourceFile);
destSteam = new FileOutputStream(destFile);
bufferedSource = new BufferedInputStream(sourceStream, 8182);
bufferedDestination = new BufferedOutputStream(destSteam, 8182);
int transfer;
System.out.println("Beginning file copy: ");
System.out.println("\tcopying "+ source);
System.out.println("\tto "+destination);
while ((transfer = bufferedSource.read()) != -1){
bufferedDestination.write(transfer);
}
}
catch (IOException e){
e.printStackTrace();
System.out.println(" An unexpected I/O error occurred.");
}
finally {
if(bufferedSource != null){
bufferedSource.close();
}
if(bufferedDestination != null){
bufferedDestination.close();
}
System.out.println("Files closed. Copy complete.");
}
}
}
My UnZip class does not unzip whole the file. This class is called from another activity. My zip file is saved in the main directory of the phone's internal storage. The zip file has folders and some video.
What's wrong with this unzip?
What and how should I read file from zip' decompress and unzip is the same meaning?
Thanks for your help!
public class Unzip {
private static final String INPUT_ZIP_FILE = "sdcard/downloaded_issue.zip";
private static final String OUTPUT_FOLDER = "sdcard/Atlantis/";
public static void main()
{
Unzip unZip = new Unzip();
unZip.unZipIt(INPUT_ZIP_FILE, OUTPUT_FOLDER);
}
/**
* Unzip it
* #param zipFile input zip file
* #param outputFolder 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();
if (ze.isDirectory()) {
ze = zis.getNextEntry();
}
}
zis.closeEntry();
zis.close();
System.out.println("Done");
}catch(IOException ex){
ex.printStackTrace();
}
}
}
I think your 'while' loop is broken; you're only fetching the next entry if that next entry is a directory, while I assume you're probably trying to skip the directories.
Anyway, since you create the folders for all files you encounter, you can just skip the folder entries and write the file entries. The only exception would be the creation of empty folders.
Replacing the while-loop by this code should work:
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
if (ze.isDirectory()) {
// create the folder
newFile.mkdirs();
}
else {
// create the parent folder and write to disk
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();
}
// get the next item
ze = zis.getNextEntry();
}
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!!!
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.
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. :)