package codes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Rough {
public static void main(String[] args) throws IOException {
private static final String FOLDER_PATH = "C:\\Users\\s13w63\\Desktop\\Zip";
File dir = new File(FOLDER_PATH);
File[] files = dir.listFiles(new FilenameFilter() {
#Override
public boolean accept(File directory, String fileName) {
if (fileName.endsWith(".txt")) {
return true;
}
return false;
}
});
for (File f : files)
{
FileOutputStream fos=new FileOutputStream("C:\\Users\\s13w63\\Desktop\\Source.zip");
ZipOutputStream zos=new ZipOutputStream(fos);
ZipEntry ze=new ZipEntry(f.getCanonicalPath());
zos.putNextEntry(ze);
zos.close();
System.out.println(f.getCanonicalPath());
}
}
}
I tried this code to ZIP the files, it was showing the file names but not zipping them. Should I have to add anything..and it was showing there is error in code continue to compile??
Help me to solve this issue
Use java.nio.file; it has a very nice solution to your problem.
Illustration:
final Path zipPath = Paths.get("C:\\Users\\s13w63\\Desktop\\Source.zip");
final Path dir = Paths.get("C:\\Users\\s13w63\\Desktop\\Zip");
final DirectoryStream<Path> dirstream
= Files.newDirectoryStream(dir, "*.txt");
final URI uri = URI.create("jar:" + zipPath.toUri());
final Map<String, ?> env = Collections.emptyMap();
String filename;
try (
final FileSystem zipfs = FileSystems.newFileSystem(uri, env);
) {
for (final Path entry: dirstream) {
filename = dir.relativize(entry).toString();
Files.copy(entry, zipfs.getPath("/" + filename));
}
}
Yes, that's right, you can open a zip file as a FileSystem; as such, every operation in Files can be used "on a zip"!
This is JSR 203 for you; you even have FileSystem implementations in memory, over FTP, Dropbox, and others.
Note about the necessity to have the file name as a String: it is because you cannot .resolve() a Path against another if the other Path is from a different provider; I have published a package which solves this particular problem (among others) and has a MorePaths.resolve() method for such cases.
Bharat,
Please paste the error message that you see
Also, I see few issues with your approach.
You might need to do the below things
Take out the definition of FOS and ZOS from the for loop and move it above it...
The code to add the file is missing...
Move zos.close() after the for loop
You could use the below code to add contents of the text file to the ZipOutputStream
/**
* Adds a file to the current zip output stream
*
* #param file
* the file to be added
* #param zos
* the current zip output stream
*/
private static void addFileToZip(File file, ZipOutputStream zos) {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file))) {
zos.putNextEntry(new ZipEntry(file.getName()));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = bis.read(bytesIn)) != -1) {
zos.write(bytesIn, 0, read);
}
zos.closeEntry();
} catch (IOException e) {
//Take appropriate action
}
}
Related
I am stuck in this issue very badly. I was trying to unzip the zip file using java. I need to upload a zip file using jsp. In controller it accepts Multipart file. Then I have to unzip this file to some location say a temp directory. I did mulipartFile.transferTo('temp zipfile location'), to place a zip file. Under this location zip file will always be replaced. This (zipcopy) would be the source of zip file to be unziped later.. below is code snippet..
String zipcopy = env.getProperty("zipFileCopier");
file.transferTo(new File(zipcopy));
file is of type Multipart.
This is running well on windows environment. No issues at all. I changed the path in application.properties for Linux environment. What I found is -- it is just NOT creating any unziped directories in temp directory. I call unzip code here :
unziputility.unzip(zipcopy, destTemp);
File extractedDir = new File(destTemp+File.separator+multipartFileName+File.separator+"local");
if(extractedDir!=null && extractedDir.exists() && extractedDir.isDirectory()) {
System.out.println("TEST");
//business logic
}
TEST is not getting printed in Linux env. Also note that above code is in try catch block with ex.printstackTrace method used. However no exception is seen caught. Here is my UnzipUtility class:
UnzipUtility
package abc.xyz.re.util;
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;
import org.springframework.stereotype.Component;
#Component
public class UnzipUtility {
private static final int BUFFER_SIZE = 9096;
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 entryName = entry.getName();
String filePath = destDirectory + File.separator + entryName;
if (!entry.isDirectory()) {
extractFile(zipIn, filePath);
} else {
File dir = new File(filePath);
dir.mkdirs();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
}
private void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
}
}
above UnzipUtility when replaced with lingala zip4j..same issue. https://github.com/srikanth-lingala/zip4j.
application.properties
uploadDestTemp = /opt/temp
destDirectory = /opt/apache-tomcat-7.0.39/webapps/ROOT/root_/contents/crbt_tones
zipFileCopier = /opt/zip_download/zipfile.zip
in above application.properties file, uploadDestTemp is already created. Also zipFileCopier directory with zipfile.zip file is created
I re-tested this case by making sample code only for unziping the zip file from one location to other. Again it ran perfect in Windows. But failed in Linux. code below:
package package123;
public class Test4 {
public static void main(String[] args) {
System.out.println("testing...");
try {
UnzipUtility unzipUtility = new UnzipUtility();
String unzipLocation = "/opt/temp";
String zipFilePath = "/opt/zip_download/zipfile.zip";
unzipUtility.unzip(zipFilePath, unzipLocation);
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
someone please help me to resolve this issue. kindly tell me why I am not able to use this code on my production Linux environment.
I am trying to create a simple java program which reads and extracts the content from the file(s) inside zip file. Zip file contains 3 files (txt, pdf, docx). I need to read the contents of all these files and I am using Apache Tika for this purpose.
Can somebody help me out here to achieve the functionality. I have tried this so far but no success
Code Snippet
public class SampleZipExtract {
public static void main(String[] args) {
List<String> tempString = new ArrayList<String>();
StringBuffer sbf = new StringBuffer();
File file = new File("C:\\Users\\xxx\\Desktop\\abc.zip");
InputStream input;
try {
input = new FileInputStream(file);
ZipInputStream zip = new ZipInputStream(input);
ZipEntry entry = zip.getNextEntry();
BodyContentHandler textHandler = new BodyContentHandler();
Metadata metadata = new Metadata();
Parser parser = new AutoDetectParser();
while (entry!= null){
if(entry.getName().endsWith(".txt") ||
entry.getName().endsWith(".pdf")||
entry.getName().endsWith(".docx")){
System.out.println("entry=" + entry.getName() + " " + entry.getSize());
parser.parse(input, textHandler, metadata, new ParseContext());
tempString.add(textHandler.toString());
}
}
zip.close();
input.close();
for (String text : tempString) {
System.out.println("Apache Tika - Converted input string : " + text);
sbf.append(text);
System.out.println("Final text from all the three files " + sbf.toString());
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TikaException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
If you're wondering how to get the file content from each ZipEntry it's actually quite simple. Here's a sample code:
public static void main(String[] args) throws IOException {
ZipFile zipFile = new ZipFile("C:/test.zip");
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
InputStream stream = zipFile.getInputStream(entry);
}
}
Once you have the InputStream you can read it however you want.
As of Java 7, the NIO АРI provides a better and more generic way of accessing the contents of ZIP or JAR files. Actually, it is now a unified API which allows you to treat ZIP files exactly like normal files.
In order to extract all of the files contained inside of a ZIP file in this API, you'd do as shown below.
In Java 8
private void extractAll(URI fromZip, Path toDirectory) throws IOException {
FileSystems.newFileSystem(fromZip, Collections.emptyMap())
.getRootDirectories()
.forEach(root -> {
// in a full implementation, you'd have to
// handle directories
Files.walk(root).forEach(path -> Files.copy(path, toDirectory));
});
}
In Java 7
private void extractAll(URI fromZip, Path toDirectory) throws IOException {
FileSystem zipFs = FileSystems.newFileSystem(fromZip, Collections.emptyMap());
for (Path root : zipFs.getRootDirectories()) {
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
#Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
throws IOException {
// You can do anything you want with the path here
Files.copy(file, toDirectory);
return FileVisitResult.CONTINUE;
}
#Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
throws IOException {
// In a full implementation, you'd need to create each
// sub-directory of the destination directory before
// copying files into it
return super.preVisitDirectory(dir, attrs);
}
});
}
}
Because of the condition in while, the loop might never break:
while (entry != null) {
// If entry never becomes null here, loop will never break.
}
Instead of the null check there, you can try this:
ZipEntry entry = null;
while ((entry = zip.getNextEntry()) != null) {
// Rest of your code
}
Sample code you can use to let Tika take care of container files for you.
http://wiki.apache.org/tika/RecursiveMetadata
Form what I can tell, the accepted solution will not work for cases where there are nested zip files. Tika, however will take care of such situations as well.
My way of achieving this is by creating ZipInputStream wrapping class that would handle that would provide only the stream of current entry:
The wrapper class:
public class ZippedFileInputStream extends InputStream {
private ZipInputStream is;
public ZippedFileInputStream(ZipInputStream is){
this.is = is;
}
#Override
public int read() throws IOException {
return is.read();
}
#Override
public void close() throws IOException {
is.closeEntry();
}
}
The use of it:
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("SomeFile.zip"));
while((entry = zipInputStream.getNextEntry())!= null) {
ZippedFileInputStream archivedFileInputStream = new ZippedFileInputStream(zipInputStream);
//... perform whatever logic you want here with ZippedFileInputStream
// note that this will only close the current entry stream and not the ZipInputStream
archivedFileInputStream.close();
}
zipInputStream.close();
One advantage of this approach: InputStreams are passed as an arguments to methods that process them and those methods have a tendency to immediately close the input stream after they are done with it.
i did mine like this and remember to change url or zip files
jdk 15
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.io.*;
import java.util.*;
import java.nio.file.Paths;
class Main {
public static void main(String[] args) throws MalformedURLException,FileNotFoundException,IOException{
String url,kfile;
Scanner getkw = new Scanner(System.in);
System.out.println(" Please Paste Url ::");
url = getkw.nextLine();
System.out.println("Please enter name of file you want to save as :: ");
kfile = getkw.nextLine();
getkw.close();
Main Dinit = new Main();
System.out.println(Dinit.dloader(url, kfile));
ZipFile Vanilla = new ZipFile(new File("Vanilla.zip"));
Enumeration<? extends ZipEntry> entries = Vanilla.entries();
while(entries.hasMoreElements()){
ZipEntry entry = entries.nextElement();
// String nextr = entries.nextElement();
InputStream stream = Vanilla.getInputStream(entry);
FileInputStream inpure= new FileInputStream("Vanilla.zip");
FileOutputStream outter = new FileOutputStream(new File(entry.toString()));
outter.write(inpure.readAllBytes());
outter.close();
}
}
private String dloader(String kurl, String fname)throws IOException{
String status ="";
try {
URL url = new URL("URL here");
FileOutputStream out = new FileOutputStream(new File("Vanilla.zip")); // Output File
out.write(url.openStream().readAllBytes());
out.close();
} catch (MalformedURLException e) {
status = "Status: MalformedURLException Occured";
}catch (IOException e) {
status = "Status: IOexception Occured";
}finally{
status = "Status: Good";}
String path="\\tkwgter5834\\";
extractor(fname,"tkwgter5834",path);
return status;
}
private String extractor(String fname,String dir,String path){
File folder = new File(dir);
if(!folder.exists()){
folder.mkdir();
}
return "";
}
}
.Net guy working on a java app
I am uploading using the following example as my starting point ( I have this working). This shows using FileContent needing a java.io.File which does not contain the actual file only a pointer to the actual file.
We are uploading from a web site and attempting to insert into the drive, I would prefer to do this using a memory Stream like the .Net example. I cannot see that in looking at the FileContent class. So my questing is: Is there a way to insert a file in Google drive that is in memory and not first on the hard drive?
private static File insertFile(Drive service, String title, String description,
String parentId, String mimeType, String filename) {
// File's metadata.
File body = new File();
body.setTitle(title);
body.setDescription(description);
body.setMimeType(mimeType);
// Set the parent folder.
if (parentId != null && parentId.length() > 0) {
body.setParents(
Arrays.asList(new ParentReference().setId(parentId)));
}
// File's content.
java.io.File fileContent = new java.io.File(filename);
FileContent mediaContent = new FileContent(mimeType, fileContent);
try {
File file = service.files().insert(body, mediaContent).execute();
// Uncomment the following line to print the File ID.
// System.out.println("File ID: " + file.getId());
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
}
Override the AbstractInputStream build your own FileContent
package com;
import java.io.IOException;
import java.io.InputStream;
import com.google.api.client.http.AbstractInputStreamContent;
import com.google.api.client.util.Preconditions;
public class FileContent extends AbstractInputStreamContent {
private InputStream inputStream = null;
private long inputLength = 0;
public FileContent(String type, InputStream pInputStream) throws IOException {
super(type);
this.inputStream = Preconditions.checkNotNull(pInputStream);
this.inputLength = this.inputStream.available();
}
public long getLength() throws IOException {
return this.inputLength;
}
public boolean retrySupported() {
return false;
}
#Override
public InputStream getInputStream() throws IOException {
return this.inputStream;
}
}
I need to unzip a zipped directory containing different files' format like .txt, .xml, .xls etc.
I am able to unzip if the directory contains only .txt files but it fails with other files format. Below is the program that I am using and after a bit of googling, all I saw was similar approach -
import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ZipUtils {
public static void extractFile(InputStream inStream, OutputStream outStream) throws IOException {
byte[] buf = new byte[1024];
int l;
while ((l = inStream.read(buf)) >= 0) {
outStream.write(buf, 0, l);
}
inStream.close();
outStream.close();
}
public static void main(String[] args) {
Enumeration enumEntries;
ZipFile zip;
try {
zip = new ZipFile("myzip.zip");
enumEntries = zip.entries();
while (enumEntries.hasMoreElements()) {
ZipEntry zipentry = (ZipEntry) enumEntries.nextElement();
if (zipentry.isDirectory()) {
System.out.println("Name of Extract directory : " + zipentry.getName());
(new File(zipentry.getName())).mkdir();
continue;
}
System.out.println("Name of Extract fille : " + zipentry.getName());
extractFile(zip.getInputStream(zipentry), new FileOutputStream(zipentry.getName()));
}
zip.close();
} catch (IOException ioe) {
System.out.println("There is an IoException Occured :" + ioe);
ioe.printStackTrace();
}
}
}
Throws the below exception -
There is an IoException Occured :java.io.FileNotFoundException: myzip\abc.xml (The system cannot find the path specified)
java.io.FileNotFoundException: myzip\abc.xml (The system cannot find the path specified)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:104)
at updaterunresults.ZipUtils.main(ZipUtils.java:43)
When you try to open the file that is going to contain the extracted content, the error occurs.
This is because the myzip folder is not available.
So check if it indeed is not available and create it before extracting the zip:
File outputDirectory = new File("myzip");
if(!outputDirectory.exists()){
outputDirectory.mkdir();
}
As #Perception pointed out in the comments: The output location is relative to the active/working directory. This is probably not very convenient, so you might want to add the extraction location to the location of the extracted files:
File outputLocation = new File(outputDirectory, zipentry.getName());
extractFile(zip.getInputStream(zipentry), new FileOutputStream(outputLocation));
(of course you need also add outputLocation to the directory creation code)
This is a good example in which he showed to unzip all the formats (pdf, txt etc) have look its quite
or you can use this code might work (i haven't tried this)
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 ZipUtils
{
private static final int BUFFER_SIZE = 4096;
private static void extractFile(ZipInputStream in, File outdir, String name) throws IOException
{
byte[] buffer = new byte[BUFFER_SIZE];
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(outdir,name)));
int count = -1;
while ((count = in.read(buffer)) != -1)
out.write(buffer, 0, count);
out.close();
}
private static void mkdirs(File outdir,String path)
{
File d = new File(outdir, path);
if( !d.exists() )
d.mkdirs();
}
private static String dirpart(String name)
{
int s = name.lastIndexOf( File.separatorChar );
return s == -1 ? null : name.substring( 0, s );
}
/***
* Extract zipfile to outdir with complete directory structure
* #param zipfile Input .zip file
* #param outdir Output directory
*/
public static void extract(File zipfile, File outdir)
{
try
{
ZipInputStream zin = new ZipInputStream(new FileInputStream(zipfile));
ZipEntry entry;
String name, dir;
while ((entry = zin.getNextEntry()) != null)
{
name = entry.getName();
if( entry.isDirectory() )
{
mkdirs(outdir,name);
continue;
}
/* this part is necessary because file entry can come before
* directory entry where is file located
* i.e.:
* /foo/foo.txt
* /foo/
*/
dir = dirpart(name);
if( dir != null )
mkdirs(outdir,dir);
extractFile(zin, outdir, name);
}
zin.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Regards
I want to check whether any Zip file is present on a specified path. If present then I want to extract that file on the same path.
How to check if any Zip file is present on a given path?
You can try this code which checks the extension of the file inside the directory and prints the filename if Zip file is present.
public static void main(String[] args)
{
// Directory path here
String path = ".";
String files;
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
for (int i = 0; i < listOfFiles.length; i++)
{
if (listOfFiles[i].isFile())
{
files = listOfFiles[i].getName();
if (files.endsWith(".rar") || files.endsWith(".zip"))
{
System.out.println(files);
}
}
}
}
Instead of that If you want to use FilenameFilter as told by Andrew Thompson.
You can implement FilenameFilter in your class.
More help is given on this link.
By this you dont need to check the extension of file .
It will give you only those files which extension is being passed as a parameter.
To extract the zip file if found you can take help of the ZipInputStream package .
You can have a look here to extract the folder.
How to check if Any Zip file is present on a given path?
See File.exists()
This unzips all files in a directory, but it's easy to modify to only unzip a specific file.
package com.wedgeless.stackoverflow;
import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* Unzips all zip files in a directory
* #author mk
*/
public final class Unzipper
{
public static final String DOT_ZIP = ".ZIP";
public static final FilenameFilter DOT_ZIP_FILTER = new FilenameFilter()
{
#Override
public boolean accept(File dir, String name)
{
return name.toUpperCase().endsWith(DOT_ZIP);
}
};
public static void main(String[] args)
{
File dir = new File("/path/to/dir");
Unzipper unzipper = new Unzipper();
unzipper.unzipDir(dir);
}
public void unzipDir(File dir)
{
for (File file : dir.listFiles(DOT_ZIP_FILTER))
{
unzip(file);
}
}
protected void unzip(File file)
{
File dir = getZipDir(file);
try
{
dir.mkdirs();
ZipFile zip = new ZipFile(file);
Enumeration<? extends ZipEntry> zipEntries = zip.entries();
while (zipEntries.hasMoreElements())
{
ZipEntry zipEntry = zipEntries.nextElement();
File outputFile = new File(dir, zipEntry.getName());
outputFile.getParentFile().mkdirs();
if (!zipEntry.isDirectory())
{
write(zip, zipEntry, outputFile);
}
}
}
catch (IOException e)
{
dir.delete();
}
}
protected void write(ZipFile zip, ZipEntry zipEntry, File outputFile)
throws IOException
{
final BufferedInputStream input = new BufferedInputStream(zip.getInputStream(zipEntry));
final int buffsize = 1024;
final byte buffer[] = new byte[buffsize];
final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(outputFile), buffsize);
try
{
while (input.available() > 0)
{
input.read(buffer, 0, buffsize);
output.write(buffer, 0, buffsize);
}
}
finally
{
output.flush();
output.close();
input.close();
}
}
protected File getZipDir(File zip)
{
File dir = zip.getParentFile();
int index = zip.getName().toUpperCase().lastIndexOf(DOT_ZIP);
String zipPath = zip.getName().substring(0, index);
File zipDir = new File(dir, zipPath);
return zipDir;
}
}
It's also not puzzled when on those rare occasions you get zip files with a extension in a non-standard case e.g. file.ZIP
edit: I guess I should have read the question more carefully. You only asked how to identify if a zip file existed on a path, not how to extract it. Just use the FilenameFilter approach... if you get any hits return true, otherwise false.
Take a File variable and go through all the files inside the director and ckeck for a .zip or .tar.gz or .rar
How to iterate over the files of a certain directory, in Java?
The best way to test the availability of any resource that you want to use is just to try to use it. Any other technique is vulnerable to timing-window problems, critique that you are trying to predict the future, double coding, etc. etc. etc. Just catch the FileNotFoundException that happens when you try to open it. You have to catch it anyway, why write the same code twice?