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.
Related
I'm programming in an online IDE (it is studio.code.org) (For a programming course). I would like to switch to a local IDE, but the online IDE uses some imports that are unavailable to download, but can be used in the code that has been written in the online IDE. This is in java. To make this a more general form of question that applies to (and will help) most people:
This is in java. I'm trying to print the contents of a file out in the console whose path is unknown, but is used as an import. Is it possible? If so, what code do I need to run to print the file out in console (from where I can copy paste it and use it elsewhere).
Here's the source code for something I tried to make this happen (but it didn't work, I'll show what output I got from the console below the code):
import java.io.*;
import org.code.neighborhood.Painter;
public class MyNeighborhood {
public static void main(String[] args) {
try {
Class<?> cls = Class.forName("org.code.neighborhood.Painter");
String fileName = cls.getName().replace('.', File.separatorChar) + ".class";
File file = new File(fileName);
System.out.println("File path: " + file.getAbsolutePath());
FileInputStream fis = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
fis.read(buffer);
fis.close();
System.out.println(new String(buffer));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output from console:
[JAVALAB] Connecting...
[JAVALAB] Compiling...
[JAVALAB] Compilation successful.
[JAVALAB] Running...
File path: /tmp/org/code/neighborhood/Painter.class
As you may have noticed I have found a file, but it is empty, although I know that the real file that is being imported is certainly not empty.
I do have read access to the system as well since I am able to navigate the root folder by using the code below:
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
boolean readContent = false; // change this to true to read file content, false to read file names
File directory = new File("/");
if (readContent) {
String fileName = "";
readFileContent(directory, fileName);
} else {
String[] fileNames = readFileNames(directory);
if (fileNames == null) {
System.out.println("Directory not found.");
} else {
System.out.println("Files in the directory:");
for (String fileName : fileNames) {
File file = new File(directory, fileName);
if (file.isDirectory()) {
System.out.println("Directory: " + fileName);
} else if (file.isFile()) {
System.out.println("File: " + fileName);
}
}
}
}
}
private static void readFileContent(File directory, String fileName) {
File file = new File(directory, fileName);
if (file.isFile()) {
try (FileReader reader = new FileReader(file)) {
int c;
while ((c = reader.read()) != -1) {
System.out.print((char) c);
}
} catch (IOException e) {
System.out.println("Error reading file: " + e.getMessage());
}
} else {
System.out.println("File not found.");
}
}
private static String[] readFileNames(File directory) {
if (directory.isDirectory()) {
return directory.list();
}
return null;
}
}
I am creating an Android module in react-native
I never worked with Java or writing code in Java
How can I complete the code below?
What I want
1- look and verify if the directory exist if it exist then remove it.
2- recreate the directory.
3- create a json file and add its content.
Here is what I got so far
#ReactMethod
public string write(string content) {
var folder = "NovelManager";
File path = Paths.get(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), folder);
var fullPath = Paths.get(path, "NovelManager.backup.json");
makeDir(path);
File file = new File(path, "NovelManager.backup.json");
if (!file.exists())
file = file.createNewFile();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
out.write(content);
out.close();
return file.getAbsolutePath();
}
private void makeDir(string dirPath){
var dir = new File(dirPath);
if (!dir.exists())
dir.mkdir();
}
Update and solution
After to much hard work this did thing for me.
Here is the complete code for anyone who have similar problem.
// DownloadFileModule.java
package com.novelmanager;
import android.view.View;
import android.app.Activity;
import java.io.BufferedWriter;
import java.io.Console;
import java.io.File;
import java.io.FileWriter;
import android.os.Environment;
import java.io.OutputStreamWriter;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.UiThreadUtil;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
public class DownloadFileModule extends ReactContextBaseJavaModule {
#Override
public String getName() {
return "DownloadFileModule";
}
#ReactMethod(isBlockingSynchronousMethod = true)
public String write(String content) {
if (content == null || content == "")
return "";
try {
String folder = "NovelManager";
String fileName = "NovelManager.backup.json";
String downloadFolderPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getPath();
String dirPath = compine(downloadFolderPath, folder);
File dir = new File(dirPath);
if (!dir.exists())
dir.mkdir();
String path = compine(downloadFolderPath, folder, fileName);
File file = new File(path);
if (!file.exists())
file.createNewFile();
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
out.write(content);
out.close();
return file.getPath();
} catch (Exception e) {
return e.getMessage();
}
}
private String compine(String... more) {
String url = more[0];
for (int i = 1; i < more.length; i++) {
String str = more[i];
if (str.startsWith("/"))
str = str.substring(1);
if (str.endsWith("/"))
str = str.substring(0, str.length() - 1);
if (url.endsWith("/"))
url = url.substring(0, url.length() - 1);
url = url + "/" + str; // relative url
}
return url; // relative url
}
DownloadFileModule(ReactApplicationContext reactContext) {
super(reactContext);
}
}
To delete directory
public boolean deleteDirectory(Path pathToBeDeleted) throws IOException {
Files.walk(pathToBeDeleted)
.sorted(Comparator.reverseOrder())
.map(Path::toFile)
.forEach(File::delete);
return !Files.exists(pathToBeDeleted);
}
To write to file
public void writeToFile(String content, File file) throws IOException {
Files.write(file.toPath(), content.getBytes());
}
You can use Apache FileUtils to perform all the required operations for e.g.
Reference : https://commons.apache.org/proper/commons-io/javadocs/api-2.5/index.html?org/apache/commons/io/FileUtils.html
FileUtils.cleanDirectory(path); //clean out directory (this is optional)
FileUtils.forceDelete(path); //delete directory
FileUtils.forceMkdir(path); //create directory
FileUtils.touch(file)); //create new file
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
}
}
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?