Extracting tar.gz using java error - java

I am trying to extract an archive .tar.gz using java and I am getting Directory error that I do not seem to understand. Please help. I got this sample code from https://forums.oracle.com/forums/thread.jspa?threadID=2065236
package untargz;
import java.io.*;
import com.ice.tar.*;
import javax.activation.*;
import java.util.zip.GZIPInputStream;
/**
*
* #author stanleymungai
*/
public class Untargz {
public static InputStream getInputStream(String tarFileName) throws Exception{
if(tarFileName.substring(tarFileName.lastIndexOf(".") + 1, tarFileName.lastIndexOf(".") + 3).equalsIgnoreCase("gz")){
System.out.println("Creating an GZIPInputStream for the file");
return new GZIPInputStream(new FileInputStream(new File(tarFileName)));
}else{
System.out.println("Creating an InputStream for the file");
return new FileInputStream(new File(tarFileName));
}
}
private static void untar(InputStream in, String untarDir) throws IOException {
System.out.println("Reading TarInputStream... ");
TarInputStream tin = new TarInputStream(in);
TarEntry tarEntry = tin.getNextEntry();
if(new File(untarDir).exists()){
while (tarEntry != null){
File destPath = new File(untarDir + File.separatorChar + tarEntry.getName());
System.out.println("Processing " + destPath.getAbsoluteFile());
if(!tarEntry.isDirectory()){
FileOutputStream fout = new FileOutputStream(destPath);
tin.copyEntryContents(fout);
fout.close();
}else{
destPath.mkdir();
}
tarEntry = tin.getNextEntry();
}
tin.close();
}else{
System.out.println("That destination directory doesn't exist! " + untarDir);
}
}
private void run(){
try {
String strSourceFile = "C:/AskulInstaller/pid.tar.gz";
String strDest = "C:/AskulInstaller/Extracted Files";
InputStream in = getInputStream(strSourceFile);
untar(in, strDest);
}catch(Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public static void main(String[] args) {
new Untargz().run();
}
}
Once I run this piece of code, this is My Output;
Creating an GZIPInputStream for the file
Reading TarInputStream...
That destination directory doesn't exist! C:/AskulInstaller/Extracted Files
BUILD SUCCESSFUL (total time: 0 seconds)
When I Manually Create the destination Directory C:/AskulInstaller/Extracted Files
I get this Error Output;
Creating an GZIPInputStream for the file
Reading TarInputStream...
Processing C:\AskulInstaller\Extracted Files\AskulInstaller\pid\Askul Logs\DbLayer_AskulMain_10_Apr_2013_07_44.log
java.io.FileNotFoundException: C:\AskulInstaller\Extracted Files\AskulInstaller\pid\Askul Logs\DbLayer_AskulMain_10_Apr_2013_07_44.log (The system cannot find the path specified)
C:\AskulInstaller\Extracted Files\AskulInstaller\pid\Askul Logs\DbLayer_AskulMain_10_Apr_2013_07_44.log (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:165)
at untargz.Untargz.untar(Untargz.java:37)
at untargz.Untargz.run(Untargz.java:55)
at untargz.Untargz.main(Untargz.java:64)
Is there a way I am supposed to place My directories so that the extraction Happens or what exactly is My Mistake?

If the tar file contains an entry for a file foo/bar.txt but doesn't contain a previous directory entry for foo/ then your code will be trying to create a file in a directory that doesn't exist. Try adding
destFile.getParentFile().mkdirs();
just before you create the FileOutputStream.
Alternatively, if you don't mind your code depending on Ant as a library then you can delegate the whole unpacking process to an Ant task rather than doing it by hand. Something like this (not fully tested):
Project p = new Project();
Untar ut = new Untar();
ut.setProject(p);
ut.setSrc(tarFile);
if(tarFile.getName().endsWith(".gz")) {
ut.setCompression((UntarCompressionMethod)EnumeratedAttribute.getInstance(UntarCompressionMethod.class, "gzip"));
}
ut.setDest(destDir);
ut.perform();

Related

Java - IOException: The system cannot find path specified

import java.io.File;
import java.io.IOException;
public class TestFile {
public static void main(String[] args) {
String separator = File.separator;
String filename = "myFile.txt";
String directory = "mydir1" + separator + "mydir2";
File f = new File(directory,filename);
if (f.exists()) {
System.out.print("filename:" + f.getAbsolutePath());
System.out.println("filesize:" + f.length());
} else {
f.getParentFile().getParentFile().mkdir();
try{
f.createNewFile();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
What I am trying to do is create file "myFile.txt" under the folder "mydir1", but the console says "the system cannot find the path specified", can someone tell me where did I do wrong? Thanks in advance.
It looks like you create only mydir1 but not mydir2.
I can suggest instead of
f.getParentFile().getParentFile().mkdir();
try something like:
f.getParentFile().mkdirs();
File.mkdirs will try to create all required parrent directories.

Add files and repertories to a Tar archive with Apache Commons Compress library in non machine dependent way

I'm working on an application that need to create a tar archive in order to calculate his hash.
But I encounter some problems :
the tar is not the same in different machine, then the hash calculated is different
I'm not able to add directories properly
If I add an zip file, at the end, in the tar, I have the content off my zip file :/
I have read different post in SO and the dedicated tutorial on apache, and also the source test code of the apache commons compress jar, but I don't get the right solution.
Are there anybody that can find where my code is not correct ?
public static File createTarFile(File[] files, File repository) {
File tarFile = new File(TEMP_DIR + File.separator + repository.getName() + Constants.TAR_EXTENSION);
if (tarFile.exists()) {
tarFile.delete();
}
try {
OutputStream out = new FileOutputStream(tarFile);
TarArchiveOutputStream aos = (TarArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("tar", out);
for(File file : files){
Utilities.addFileToTar(aos, file, "");
}
aos.finish();
aos.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return tarFile;
}
private static void addFileToTar(TarArchiveOutputStream tOut, File file, String base) throws IOException {
TarArchiveEntry entry = new TarArchiveEntry(file, base + file.getName());
entry.setModTime(0);
entry.setSize(file.length());
entry.setUserId(0);
entry.setGroupId(0);
entry.setUserName("avalon");
entry.setGroupName("excalibur");
entry.setMode(0100000);
entry.setSize(file.length());
tOut.putArchiveEntry(entry);
if (file.isFile()) {
IOUtils.copy(new FileInputStream(file), tOut);
tOut.closeArchiveEntry();
} else {
tOut.closeArchiveEntry();
File[] children = file.listFiles();
if (children != null) {
for (File child : children) {
addFileToTar(tOut, child, file.getName());
}
}
}
}
Thank you.
I finally found the solution after reading the post of caarlos0 : Encoding problem when compressing files with Apache Commons Compression on Linux
Using the apache-commons-1.8.jar library, I have made a tool class that can do the job :
You can find this code here : GitHub repository of the library MakeTar
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
/**
* The Class TarArchive.
*/
public class TarArchive {
/**
* Creates the tar of files.
*
* #param files the files
* #param tarPath the tar path
* #throws IOException Signals that an I/O exception has occurred.
*/
public static void createTarOfFiles(String[] files, String tarPath) throws IOException
{
FileOutputStream fOut = null;
BufferedOutputStream bOut = null;
TarArchiveOutputStream tOut = null;
Arrays.sort(files);
try
{
fOut = new FileOutputStream(new File(tarPath));
bOut = new BufferedOutputStream(fOut);
tOut = new TarArchiveOutputStream(bOut);
for (String file : files) {
addFileToTar(tOut, file, "");
}
}
finally
{
tOut.finish();
tOut.close();
bOut.close();
fOut.close();
}
}
/**
* Creates the tar of directory.
*
* #param directoryPath the directory path
* #param tarPath the tar path
* #throws IOException Signals that an I/O exception has occurred.
*/
public static void createTarOfDirectory(String directoryPath, String tarPath) throws IOException
{
FileOutputStream fOut = null;
BufferedOutputStream bOut = null;
TarArchiveOutputStream tOut = null;
try
{
fOut = new FileOutputStream(new File(tarPath));
bOut = new BufferedOutputStream(fOut);
tOut = new TarArchiveOutputStream(bOut);
addFileToTar(tOut, directoryPath, "");
}
finally
{
tOut.finish();
tOut.close();
bOut.close();
fOut.close();
}
}
/**
* Adds the file to tar.
*
* #param tOut the t out
* #param path the path
* #param base the base
* #throws IOException Signals that an I/O exception has occurred.
*/
private static void addFileToTar(TarArchiveOutputStream tOut, String path, String base) throws IOException
{
File f = new File(path);
String entryName = base + f.getName();
TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
if(f.isFile())
{
tarEntry.setModTime(0);
tOut.putArchiveEntry(tarEntry);
IOUtils.copy(new FileInputStream(f), tOut);
tOut.closeArchiveEntry();
}
else
{
File[] children = f.listFiles();
Arrays.sort(children);
if(children != null)
{
for(File child : children)
{
addFileToTar(tOut, child.getAbsolutePath(), entryName + "/");
}
}
}
}
}
Thanks for read me.
EDIT : Little correction, I have add the sort of the arrays.
EDIT 2 : I have corrected the code in order to have the same archive on all machine. The hash calculated on the archive is the same everywhere.

How to extract tgz file using java

Is there any java code which extracts 'tgz' file.
I searched a lot but didn't get any. So i first converted it into tar file and then i used code to extract tar file.
But my tar file contains xml, sh and tgz files so it is getting stucked.
code is:
public class test1 {
public static void main(String[] args) throws Exception{
File file = new File("D:\\Delta\\Interactive\\qml_windows\\development\\onemedia\\");
final List<File> untaredFiles = new LinkedList<File>();
final InputStream is = new FileInputStream("D:\\onemedia\\onemedia-dal-504-v4.tar");
final TarArchiveInputStream debInputStream = (TarArchiveInputStream) new ArchiveStreamFactory().createArchiveInputStream("tar", is);
TarArchiveEntry entry = null;
while ((entry = (TarArchiveEntry)debInputStream.getNextEntry()) != null) {
final File outputFile = new File(file, entry.getName());
if (entry.isDirectory()) {
if (!outputFile.exists()) {
if (!outputFile.mkdirs()) {
throw new IllegalStateException(String.format("Couldn't create directory %s.", outputFile.getAbsolutePath()));
}
}
} else {
final OutputStream outputFileStream = new FileOutputStream(outputFile);
IOUtils.copy(debInputStream, outputFileStream);
outputFileStream.close();
}
untaredFiles.add(outputFile);
}
debInputStream.close();
}
}
This code extracts tar file.
Still i am getting error as:
Exception in thread "main" java.io.FileNotFoundException: D:\onemedia\onemedia_4\adload.tgz (The system cannot find the path specified)

Java UnZipper error?

I'm making a client updater & I'm getting an error in my cmd whilst trying to unzip the file.
What it's supposed to do is:
check if the file exists in the user's home (user.home),
if it doesn't exist in the user's home, check if the file exists in the project's directory,
if it doesn't exist in the project's directory, download the file; if it does, then unzip the file into the user's home.
The error:
Exists in Directory!
file unzip : C:\Users\Ryan T\Desktop\Rezzion Updater\.rezzion.cache\rezzion.cache
java.io.FileNotFoundException: .rezzion.cache\rezzion.cache\Data (The system cannot find the path specified)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(Unknown Source)
at java.io.FileOutputStream.<init>(Unknown Source)
at rezzion.UnZip.unZipIt(UnZip.java:54)
at rezzion.Downloader.<init>(Downloader.java:68)
at rezzion.Downloader.main(Downloader.java:78)
file unzip : C:\Users\Ryan T\Desktop\Rezzion Updater\.rezzion.cache\rezzion.cache\Data
Image of Project Folder:
my Downloader.java (Main Class):
package rezzion;
import java.awt.FlowLayout;
public class Downloader extends JFrame {
private static final long serialVersionUID = 1L;
private static boolean exists = (new File(System.getProperty("user.home") + ".rezzion.cache")).exists();
private static boolean existsinDir = (new File("rezzion.cache.zip")).exists();
private static String site = "https://dl.dropboxusercontent.com/s/yoh4d17gfgnv2od/rezzion.cache.zip?dl=1&token_hash=AAE1qdxL_-2y_arb8MBnk8AHSsuhLH1-lwSiGVc0ayQKXA";
private static String filename = "rezzion.cache.zip";
private static final String INPUT_ZIP_FILE = "rezzion.cache.zip";
private static final String OUTPUT_FOLDER = ".rezzion.cache";
private final int BUFFER = 1024;
public Downloader() {
JFrame frm = new JFrame();
JProgressBar current = new JProgressBar(0, 100);
current.setBounds(35, 68, 326, 30);
current.setValue(0);
current.setStringPainted(true);
frm.setVisible(true);
frm.getContentPane().setLayout(null);
frm.setSize(400, 200);
frm.setDefaultCloseOperation(EXIT_ON_CLOSE);
if (!exists) {
if (!existsinDir) {
frm.getContentPane().add(current);
try {
URL url = new URL(site);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
int filesize = connection.getContentLength();
float totalDataRead = 0;
java.io.BufferedInputStream in = new java.io.BufferedInputStream(connection.getInputStream());
java.io.FileOutputStream fos = new java.io.FileOutputStream(filename);
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos, BUFFER);
byte[] data = new byte[BUFFER];
int i = 0;
while ((i = in.read(data, 0, BUFFER)) >= 0) {
totalDataRead = totalDataRead + i;
bout.write(data, 0, i);
float Percent = (totalDataRead * 100) / filesize;
current.setValue((int) Percent);
if (current.getValue() == 99) {
current.setValue(100);
}
}
bout.close();
in.close();
} catch (Exception e) {
javax.swing.JOptionPane.showConfirmDialog((java.awt.Component) null, e.getMessage(), "Error", javax.swing.JOptionPane.DEFAULT_OPTION);
}
} else {
System.out.println("Exists in Directory!");
UnZip unZip = new UnZip();
unZip.unZipIt(INPUT_ZIP_FILE, OUTPUT_FOLDER);
//TODO: Exists in Directory
}
} else {
System.out.println("Exists in User.Home!");
//TODO: Exists in User.Home
}
}
public static final void main(String[] args) throws Exception {
new Downloader();
}
/**
*
*/
public static void unzipComplete() {
//TODO
System.out.println("unzip Complete!");
}
}
My UnZip.java (Self Explanatory):
package rezzion;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class UnZip {
List<String> fileList;
private static final String OUTPUT_FOLDER = ".rezzion.cache";
public void unZipIt(String zipFile, String outputFolder) {
byte[] buffer = new byte[1024];
try {
// create output directory is not exists
File folder = new File(System.getProperty("user.home")
+ 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();
ze = zis.getNextEntry();
}
zis.closeEntry();
zis.close();
System.out.println("Done");
Downloader.unzipComplete();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Sorry for the poor formatting of this post, but if anyone can help I've been reading this error for a bit & looking at exactly what it's telling me to, tried merging the classes & no luck. Thanks to those that are willing to point something out, even if it's obvious & I'm missing it.
Since this is apparently a desktop app., the answer seems obvious to me. For deploying Java desktop apps., the best option is usually to install the app. using Java Web Start. JWS works on Windows, OS X & *nix.
JWS provides many appealing features including, but not limited to, splash screens, desktop integration, file associations, automatic update (including lazy downloads and programmatic control of updates), partitioning of natives & other resource downloads by platform, architecture or locale, configuration of run-time environment (minimum J2SE version, run-time options, RAM etc.), easy management of common resources using extensions..
..is there a way I could just keep this?
No.
Using automatic updates, you would abandon all that and simply let the JWS client handle it.
The 'programmatic control of updates' uses an API only available to apps. launched using JWS, specifically the DownloadServiceListener.

Java:Unzipping a file, without creating target folder

I have a nice java code that unzips a .zip file. But problem with this code is
i need to create target folders(Note:Only folders not file) before running this code.
Otherwise i will get path not found exception.
So This code wont work if zip file content is not known before. so i think this is useless code. Anyone have better logic? or Bellow code need to be edited?
package com.mireader;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
*
* #author jon
*/
public class Decompress {
private String _zipFile;
private String _location;
public Decompress(String zipFile, String location) {
_zipFile = zipFile;
_location = location;
_dirChecker("");
}
public void unzip() {
try {
FileInputStream fin = new FileInputStream(_zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
byte[] buffer = new byte[1024];
int length;
int i=0;
while ((ze = zin.getNextEntry()) != null) {
Log.v("t", ze.toString());
Log.v("Decompress", "Unzipping " + ze.getName());
if(ze.isDirectory()) {
Log.i("my","Comes to if");
_dirChecker(ze.getName());
}
else {
Log.i("my","Comes to else");
FileOutputStream fout = new FileOutputStream(_location + ze.getName());
while ((length = zin.read(buffer))>0) {
fout.write(buffer, 0, length);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
Log.i("My tag","Success");
}catch(Exception e) {
Log.e("Decompress", "unzip", e);
}
}
private void _dirChecker(String dir) {
File f = new File(_location + dir);
if(!f.isDirectory()) {
Log.i("mytag", "Creating new folder");
f.mkdirs();
System.out.print("stp:"+f.getName());
}
}
}
You can avoid the following piece of code
if(ze.isDirectory()) {
Log.i("my","Comes to if");
_dirChecker(ze.getName());
}
and add code similar to the one below in the file creator else part. It worked for me by creating the entire parent folders.
File file = createFile((baseDirectory +"/" + zipFile.getName()));
file.getParentFile().mkdirs();
It doesn't look that wrong, what exactly is your problem?
You create the directories as they appear in the zip file; I usually do it inline, but it's the same. Your code would fail if your zip file not has the directory stubs inside (which could happen with zip creators in the wild), so my unzip code doublechecks the existance of the directory before extracting each file:
if (zEntry.isDirectory()) new File(destDir+zEntry.getName()).mkdirs();
else
{
String dstEntryDir=new File(destDir+zEntry.getName()).getParent()+File.separator;
if (!fileExists(dstEntryDir)) new File(dstEntryDir).mkdirs();
copyStreamToFile(zFile.getInputStream(zEntry),destDir+zEntry.getName());
}

Categories