I have successfully extracted *.gz from *.tgz and now I have no idea how to actually extract final files from *.tgz.
There are some options using custom packages but that's not an option for me, I need to use standard Java packages only.
What I tried is using same function that I use for *.tgz for *.gz but it doesn't work.
java.util.zip.ZipException: Not in GZIP format 1.gz
Here is function that is extracting *.tgz files.
public String ExtractFile(String path) {
try {
File newFile = new File(this.getFullPathWithoutExtension(path) + ".gz");
GZIPInputStream gStream;
FileOutputStream outStream;
try (FileInputStream fileStream = new FileInputStream(path)) {
gStream = new GZIPInputStream(fileStream);
outStream = new FileOutputStream(newFile);
byte[] buf = new byte[1024];
int len;
while ((len = gStream.read(buf)) > 0) {
outStream.write(buf, 0, len);
}
}
gStream.close();
outStream.close();
newFile.createNewFile();
return newFile.getPath();
} catch (Exception e) {
System.out.print(e);
}
return null;
}
TL;DR; *.tgz files extracted to *.gz files, however *.gz files cannot be extracted.
A .tgz file wouldn't normally be extracted to a .gz file - it would be extracted to a .tar file. (A .gz file is gzipped; a .tar file is an uncompressed archive containing multiple files; a .tgz is a .tar file that's then been gzipped - you've already "undone" the gzipping.)
I don't think there's anything within Java's standard libraries to handle tar files - so you'll either have to revisit your "I can't use anything not in the standard library" decision or reimplement it yourself. The file format is easily available if you decide to do that.
Related
While Uncompressing .7z file, Empty folders are ignored, I want to consider Empty folders as well after uncompressing any .7z file.
My Code is as below
SevenZFile sevenZFile = new SevenZFile(new File(filename));
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null){
if (entry.isDirectory()){
continue;
}
File curfile = new File(DestinationPath,entry.getName());
File parent = curfile.getParentFile();
if (!parent.exists()) {
parent.mkdirs();
}
FileOutputStream out = new FileOutputStream(curfile);
byte[] content = new byte[(int) entry.getSize()];
sevenZFile.read(content, 0, content.length);
out.write(content);
out.close();
Your code seems working.
Probably the folder aren't in the "yourfile.7zip" from the beginning.
This is a common issue of 7zip and you have to update your 7zip version.
If the 7Zip contains proper arguments just use:
if (entry.isDirectory()){
new File(DestinationPath,entry.getName()).mkdir();
continue;
}
Since:
A file output stream is an output stream for writing data to a File or
to a FileDescriptor.
That is the proper method to accomplish the task because there's no folder implementation by native library vendor.
I have a zip file and I want to replace one file inside it with another file. So do not need to delete a zip entry just replace the file for the zip entry with another.
Here is what I have tried.
public void replaceConfigurationFile(ZipFile zipFile, ZipOutputStream zos, String pathToNewFile, String configFileToReplaced)
throws IOException {
String zipEntryName;
for(Enumeration<?> e = zipFile.entries(); e.hasMoreElements(); ) {
ZipEntry entryIn = (ZipEntry) e.nextElement();
zipEntryName = entryIn.getName();
if(zipEntryName.endsWith(configFileToReplaced)) {
FileInputStream fis = new FileInputStream(pathToNewFile);
ZipEntry zipEntry = new ZipEntry(zipEntryName);
zos.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zos.write(bytes, 0, length);
}
zos.closeEntry();
fis.close();
} else {
zos.putNextEntry(entryIn);
InputStream is = zipFile.getInputStream(entryIn);
byte [] buf = new byte[1024];
int len;
while((len = (is.read(buf))) > 0) {
zos.write(buf, 0, len);
}
zos.closeEntry();
}
} // enf of for
}
I have a file zip Entry named :
WEB-INF/classes/config/app-dev.yml
and I have a file at location d drive at location
D:/app-dev.yml
I am able to copy the file in to a different zip file by replacing the file i want to replace . But that is really not needed (to create a different file).
So what should I do to just replace the file with my custom file.
I have searched different posts in Stackoverflow, but unable to find what i need. I read that zip entry cannot be deleted but what about replacing it ? Please help
Your problem is that the new file might be larger than the old file - or smaller! You need to do exactly what you did to allow for the change. The probability that the new file, ZIPped, is exactly the same size as the previous one is virtually nil.
The standard Java ZIP file libraries do not allow you to update an existing ZIP file. You need to use a third party library. A Google search should find you a number of alternatives.
But you need to be aware of a couple of things:
If your application ... or system ... crashes while updating the ZIP file, the file may be corrupted.
When a ZIP file is updated, the replacement version of the file will be appended to the ZIP. The old version of the will still be in the ZIP ... but not in the ZIP file index. Hence updating a ZIP file (without rewriting it) wastes disk space.
I have the following situation:
I am able to zip my files with the following method:
public boolean generateZip(){
byte[] application = new byte[100000];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// These are the files to include in the ZIP file
String[] filenames = new String[]{"/subdirectory/index.html", "/subdirectory/webindex.html"};
// Create a buffer for reading the files
try {
// Create the ZIP file
ZipOutputStream out = new ZipOutputStream(baos);
// Compress the files
for (int i=0; i<filenames.length; i++) {
byte[] filedata = VirtualFile.fromRelativePath(filenames[i]).content();
ByteArrayInputStream in = new ByteArrayInputStream(filedata);
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(filenames[i]));
// Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(application)) > 0) {
out.write(application, 0, len);
}
// Complete the entry
out.closeEntry();
in.close();
}
// Complete the ZIP file
out.close();
} catch (IOException e) {
System.out.println("There was an error generating ZIP.");
e.printStackTrace();
}
downloadzip(baos.toByteArray());
}
This works perfectly and I can download the xy.zip which contains the following directory and file structure:
subdirectory/
----index.html
----webindex.html
My aim is to completely leave out the subdirectory and the zip should only contain the two files. Is there any way to achieve this?
(I am using Java on Google App Engine).
Thanks in advance
If you are sure the files contained in the filenames array are unique if you leave out the directory, change your line for constructing ZipEntrys:
String zipEntryName = new File(filenames[i]).getName();
out.putNextEntry(new ZipEntry(zipEntryName));
This uses java.io.File#getName()
You can use Apache Commons io to list all your files, then read them to an InputStream
Replace the line below
String[] filenames = new String[]{"/subdirectory/index.html", "/subdirectory/webindex.html"}
with the following
Collection<File> files = FileUtils.listFiles(new File("/subdirectory"), new String[]{"html"}, true);
for (File file : files)
{
FileInputStream fileStream = new FileInputStream(file);
byte[] filedata = IOUtils.toByteArray(fileStream);
//From here you can proceed with your zipping.
}
Let me know if you have issues.
You could use the isDirectory() method on VirtualFile
I need to unzip a set of files that are a zip archive. This isn't a set of zip files, this is one big zip file that has been broken up into multiple zip files based on a size requirement.
For example if you have a 2.5MB zip file and your mail system only supports 1MB files, you can ask Zip to create 3 files of at most 1MB.
So it creates a.zip.001, a.zip.002, a.zip.003 ... different libraries name them differently but essentially they all work the same way.
How do you unzip this in java? It doesn't look like the compression libs in std supports this.
Thanks.
Try to concatenate all the files into a single file and then extract the single file. Something like:
File dir = new File("D:/arc");
FileOutputStream fos = new FileOutputStream(new File(
"d:/arc/archieve-full.zip"));
FileInputStream fis = null;
Set<String> files = new TreeSet<String>();
for (String fname : dir.list()) {
files.add(fname);
}
for (String fname : files) {
try {
fis = new FileInputStream(new File(dir.getAbsolutePath(), fname));
byte[] b = new byte[fis.available()];
fis.read(b);
fos.write(b);
} finally {
if (fis != null) {
fis.close();
}
fos.flush();
}
}
fos.close();
ZipFile zipFile = new ZipFile("d:/arc/archieve-full.zip");
/*extract files from zip*/
Update: used a TreeSet to sort the file names, as dir.list() doesn't guarantee alphabetical order.
What is the Java equivalent to this jar command:
C:\>jar cvf myjar.jar directory
I'd like to create this jar file programmatically as I can't be assured that the jar command will be on the system path where I could just run the external process.
Edit: All I want is to archive (and compress) a directory. Doesn't have to follow any java standard. Ie: a standard zip is fine.
// These are the files to include in the ZIP file
String[] source = new String[]{"source1", "source2"};
// Create a buffer for reading the files
byte[] buf = new byte[1024];
try {
// Create the ZIP file
String target = "target.zip";
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(target));
// Compress the files
for (int i=0; i<source.length; i++) {
FileInputStream in = new FileInputStream(source[i]);
// Add ZIP entry to output stream.
out.putNextEntry(new ZipEntry(source[i]));
// Transfer bytes from the file to the ZIP file
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// Complete the entry
out.closeEntry();
in.close();
}
// Complete the ZIP file
out.close();
} catch (IOException e) {
}
You can also use the answer from this post How to use JarOutputStream to create a JAR file?
Everything you'll want is in the java.util.jar package:
http://java.sun.com/javase/6/docs/api/java/util/jar/package-summary.html