How to extract tgz file using java - 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)

Related

How to put a .tar file inside a .tar.gz file using Java?

Im looking to create a .tar.gz that contains sub directories that are .tar files.
I have two seperate things working right now, I am able to create a data.tar file with the needed information inside. I also have a .tar.gz working, but the subdirectories are not .tar files, for example:
data.tar (Working)
|-directory/
|--files
file.tar.gz (Working)
|-data/
|--directory/
|---files
Goal:
file.tar.gz (Not Working)
|-data.tar
|--directory/
|---files
To add a .tar to my .tar.gz i am doing the following creating a .tar file and then adding that .tar file to my .tar.gz
public class TarArchiveOutput extends Closeable {
public BufferedOutputStream bOut;
public GzipCompressorOutputStream gzOut;
public TarArchiveOutputStream tOut;
private boolean isZipped;
public TarArchiveOutput(OutputStream oStream, boolean zip) throws IOException {
bOut = null;
gzOut = null;
tOut = null;
isZipped = zip;
if(isZipped) {
bOut = new BufferedOutputStream(oStream, 1024 * 10240);
gzOut = new GzipCompressorOutputStream(bOut);
tOut = new TarArchiveOutputStream(gzOut);
tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
} else {
bOut = new BufferedOutputStream(oStream, 1024 * 10240);
tOut = new TarArchiveOutputStream(bOut);
tOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_POSIX);
}
}
public void addFileToOutput(String path, String base) throws IOException {
File f = new File(path);
if(!base.endsWith("/"))
base = base+"/";
String entryName = base + f.getName();
TarArchiveEntry tarEntry = new TarArchiveEntry(f, entryName);
tOut.putArchiveEntry(tarEntry);
if (f.isFile()) {
IOUtils.copy(new FileInputStream(f), tOut);
tOut.closeArchiveEntry();
} else {
tOut.closeArchiveEntry();
File[] children = f.listFiles();
if (children != null) {
for (File child : children) {
addFileToOutput(child.getAbsolutePath(), entryName + "/");
}
}
}
}
#Override
public void close() {
if(isZipped) gzOut.close();
tOut.close();
bOut.close();
}
}
To create just a .tar file:
TarArchiveOutput dataTarOutput = new TarArchiveOutput(new FileOutputStream(new File("data.tar")), false);
//Add files
Creating .tar.gz
TarArchiveOutput tarGZOutput = new TarArchiveOutput(new FileOutputStream(new File("file.tar.gz")), true);
tarGZOutput.addFileToOutput("data.tar", "");
I expect the format to be as follows:
file.tar.gz
|-data.tar
|--directory/
|---files
The actual result is a .tar.gz that when uncompressed/untar it contains a data.tar file but when i try to untar that it turns into a data.tar.cpgz (infinite loop), can not uncompress. Thanks in advance any help would be great!
In order to GZip the TAR archive you need to do the following:
TarArchiveOutput dataTarGzOutput = new TarArchiveOutput(new GZIPOutputStream(new FileOutputStream(new File("data.tar.gz"))), false);

How to concatenate files from an array to into a new folder? [duplicate]

This question already has answers here:
Standard concise way to copy a file in Java?
(16 answers)
Closed 6 years ago.
I am trying to write a java program that will take two arguments, dirName and fileName. The program will search for all the files in dirName that end with .java and then concatenate them into a new folder called fileName. So far I have a method to search for .java files in dirName, I then put them in a file array called list but now I am struggling to iteratively add the files in this array to my new folder, fileName. Here is what I have so far:
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.util.ArrayList;
public class TwoFiles {
File dir;
File name;
public TwoFiles(File dirName, File fileName) {
dir = dirName;
name = fileName;
}
public void setDir(File m) {
this.dir = m;
}
public File getDir() {
return dir;
}
public void setNewFolder(File n) {
this.name = n;
}
public File getNewFolder() {
return name;
}
public File[] Finder(File dir) {
dir = getDir();
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename) {
return name.endsWith(".java"); }
} );
}
public static void main(String[] args) {
File folder = null;
File newFolder = null;
Integer b = null;
TwoFiles tf = new TwoFiles(folder, newFolder);
folder = tf.getDir();
newFolder = tf.getNewFolder();
File[] list = tf.Finder(folder); //add to an array
//here is where I've been experimenting to add files in `list` to new folder, `fileName`.
for (File file : list)
{
FileInputStream inFile = new FileInputStream(file);
while ((b = inFile.read()) != -1)
newFolder.write(b);
inFile.close();
}
//copy files from array (list) into newFolder
}
}
Thanks for your time.
Your newFolder variable is of type File. You cannot write into this. I assume, your code does not even compile. You have to create an output stream in front of your loop:
FileOutputStream fos = new FileOutputStream( newFolder);
try
{
for (File file : list)
{
FileInputStream inFile = new FileInputStream(file);
while ((b = inFile.read()) != -1)
fos.write(b);
inFile.close();
}
}
finally
{
fos.close();
}
You can use the Apache Commons IO copyDirectory() with the IOFileFilter (for .java extensions) to copy your files from one directory to another. Before that you can ensure to create a new directory using forceMkdir() for your filename.
It's my version of your problem:
I created other constructor, where you can put only paths to directory/folder from you want concatenate files, and to file of concatenations result.
public class TwoFiles {
private File dir;
private File name;
public TwoFiles(File dirName, File fileName) {
dir = dirName;
name = fileName;
}
public TwoFiles(String dirName, String destinationFileName) throws IOException{
dir=new File(dirName);
if(!dir.isDirectory()){
throw new FileNotFoundException();//here your exception in case when dirName is file name instead folder name
}
name=new File(destinationFileName);
if(!name.exists()){
name.createNewFile();
}
}
public void setDir(File m) {
this.dir = m;
}
public File getDir() {
return dir;
}
public void setNewFolder(File n) {
this.name = n;
}
public File getNewFolder() {
return name;
}
public void concatenateFiles() throws IOException{
File[] files=dir.listFiles();
for(File file: files){
if(file.getName().endsWith(".java")){ //check is right file
prescribe(name, file);
}
}
}
/** prescribe file to new destination */
private void prescribe(File destination, File file) throws IOException {
FileInputStream inFile = new FileInputStream(file);
FileOutputStream writer=new FileOutputStream(destination, true); //true means next file will be write beginning from end of the file
int x;
while((x=inFile.read())!=-1){
writer.write(x);
}
String test="\n"; //next line in file
writer.write(test.getBytes());
writer.close();
inFile.close();
}
public static void main(String...strings){
String dirName="C/myApp/model/entity";
String fileName="C:/Users/Dell/Desktop/temp/test.java";
try {
new TwoFiles(dirName, fileName).concatenateFiles();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

how to rename an extracted file

I'm writing a java program that will extract zip file and rename the file inside it to the zip file name. For example: the zip file name is zip.zip and the file inside it is content.txt. Here i want to extract the zip file and the content.txt has to be renamed to zip.txt. I'm trying the below program.
And here there would be only one file in the zip file
Zip.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 zip {
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));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
File oldName = new File(filePath);
System.out.println(oldName);
String str = zipFilePath.substring(zipFilePath.lastIndexOf("\\") + 1, zipFilePath.lastIndexOf("."));
System.out.println(str);
File zipPath = new File(zipFilePath);
System.out.println(zipPath.getParent());
File newName = new File(zipPath.getParent() + "\\" + str);
System.out.println(newName);
if (oldName.renameTo(newName)) {
System.out.println("Renamed");
} else {
System.out.println("Not Renamed");
}
bos.close();
}
}
UnZip.Java
public class UnZip {
public static void main(String[] args) {
String zipFilePath = "C:\\Users\\u0138039\\Desktop\\Proview\\Zip\\New Companies Ordinance (Vol Two)_xml.zip";
String destDirectory = "C:\\Users\\u0138039\\Desktop\\Proview\\Zip";
zip unzipper = new zip();
try {
unzipper.unzip(zipFilePath, destDirectory);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Here i was able to extract the file but unable to rename it. please let me knw where am i going wrong and how to fix it.
Thanks
Close your BufferedOutputStream directly after the last write instruction (after the while loop). Only then will it release its lock on the file and will you be able to rename the file.
See: http://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html#close()

Tar a directory preserving structure with Apache in java

How can i tar a directory and preserve the directory structure using the org.apache.commons.compress libraries?
With what i am doing below, i am just getting a package that has everything flattened.
Thanks!
Here is what i have been trying and it is not working.
public static void createTar(final String tarName, final List<File> pathEntries) throws IOException {
OutputStream tarOutput = new FileOutputStream(new File(tarName));
ArchiveOutputStream tarArchive = new TarArchiveOutputStream(tarOutput);
List<File> files = new ArrayList<File>();
for (File file : pathEntries) {
files.addAll(recurseDirectory(file));
}
for (File file : files) {
TarArchiveEntry tarArchiveEntry = new TarArchiveEntry(file, file.getName());
tarArchiveEntry.setSize(file.length());
tarArchive.putArchiveEntry(tarArchiveEntry);
FileInputStream fileInputStream = new FileInputStream(file);
IOUtils.copy(fileInputStream, tarArchive);
fileInputStream.close();
tarArchive.closeArchiveEntry();
}
tarArchive.finish();
tarOutput.close();
}
public static List<File> recurseDirectory(final File directory) {
List<File> files = new ArrayList<File>();
if (directory != null && directory.isDirectory()) {
for (File file : directory.listFiles()) {
if (file.isDirectory()) {
files.addAll(recurseDirectory(file));
} else {
files.add(file);
}
}
}
return files;
}
Your problem is here:
TarArchiveEntry tarArchiveEntry = new TarArchiveEntry(file, file.getName());
Because you put each file with only it's name, not his path, in the tar.
You need to pass the relative path from your path entries to this file instead of file.getName().

Extracting tar.gz using java error

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();

Categories