I've been trying to understand why my code doesnt work on a zip and it doesnt on another..
THIS zip unzips , and THIS zip doesnt
Here is the code I use:
String zipFile = Path + FileName;
FileInputStream fin = new FileInputStream(zipFile);
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
UnzipCounter++;
if (ze.isDirectory()) {
dirChecker(ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(Path
+ ze.getName());
while ((Unziplength = zin.read(Unzipbuffer)) > 0) {
fout.write(Unzipbuffer, 0, Unziplength);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
Can anyone tell me why?
The zip doesnt work means that when it reaches the line "while ((ze = zin.getNextEntry()) != null) {".. ze is always null so it doesnt enter the loop so it doesnt extract anything.. I can open+unzip both files with WinRar..
Here's the actual error:
java.io.EOFException
at java.io.RandomAccessFile.readFully(RandomAccessFile.java:383)
at gnu.java.util.zip.ZipFile$PartialInputStream.fillBuffer(ZipFile.java:647)
Looks like your zip file is corrupt. WinRAR tends to ignore some kinds of corruption.
This is a personal gripe of mine - I believe it would be better if tools didn't do that sort of thing, because it means that whoever created the zip file probably doesn't know about the corruption either, and when you tell them, they will be all like, "but it isn't, look .. it opens in [insert broken app here]."
Related
I can go through ZipInputStream, but before starting the iteration I want to get a specific file that I need during the iteration. How can I do that?
ZipInputStream zin = new ZipInputStream(myInputStream)
while ((entry = zin.getNextEntry()) != null)
{
println entry.getName()
}
If the myInputStream you're working with comes from a real file on disk then you can simply use java.util.zip.ZipFile instead, which is backed by a RandomAccessFile and provides direct access to the zip entries by name. But if all you have is an InputStream (e.g. if you're processing the stream directly on receipt from a network socket or similar) then you'll have to do your own buffering.
You could copy the stream to a temporary file, then open that file using ZipFile, or if you know the maximum size of the data in advance (e.g. for an HTTP request that declares its Content-Length up front) you could use a BufferedInputStream to buffer it in memory until you've found the required entry.
BufferedInputStream bufIn = new BufferedInputStream(myInputStream);
bufIn.mark(contentLength);
ZipInputStream zipIn = new ZipInputStream(bufIn);
boolean foundSpecial = false;
while ((entry = zin.getNextEntry()) != null) {
if("special.txt".equals(entry.getName())) {
// do whatever you need with the special entry
foundSpecial = true;
break;
}
}
if(foundSpecial) {
// rewind
bufIn.reset();
zipIn = new ZipInputStream(bufIn);
// ....
}
(I haven't tested this code myself, you may find it's necessary to use something like the commons-io CloseShieldInputStream in between the bufIn and the first zipIn, to allow the first zip stream to close without closing the underlying bufIn before you've rewound it).
use the getName() method on ZipEntry to get the file you want.
ZipInputStream zin = new ZipInputStream(myInputStream)
String myFile = "foo.txt";
while ((entry = zin.getNextEntry()) != null)
{
if (entry.getName().equals(myFileName)) {
// process your file
// stop looking for your file - you've already found it
break;
}
}
From Java 7 onwards, you are better off using ZipFile instead of ZipStream if you only want one file and you have a file to read from:
ZipFile zfile = new ZipFile(aFile);
String myFile = "foo.txt";
ZipEntry entry = zfile.getEntry(myFile);
if (entry) {
// process your file
}
Look at Finding a file in zip entry
ZipFile file = new ZipFile("file.zip");
ZipInputStream zis = searchImage("foo.png", file);
public searchImage(String name, ZipFile file)
{
for (ZipEntry e : file.entries){
if (e.getName().endsWith(name)){
return file.getInputStream(e);
}
}
return null;
}
I'm late to the party, but all above "answers" does not answer the question and accepted "answer" suggest create temp file which is inefficient.
Lets create sample zip file:
seq 10000 | sed "s/^.*$/a/"> /tmp/a
seq 10000 20000 | sed "s/^.*$/b/"> /tmp/b
seq 20000 30000 | sed "s/^.*$/c/"> /tmp/c
zip /tmp/out.zip /tmp/a /tmp/b /tmp/c
so now we have /tmp/out.zip file, which contains 3 files, each of them full of chars a, b or c.
Now lets read it:
public static void main(String[] args) throws IOException {
ZipInputStream zipStream = new ZipInputStream(new FileInputStream("/tmp/out.zip"));
ZipEntry zipEntry;
while ((zipEntry = zipStream.getNextEntry()) != null) {
String name = zipEntry.getName();
System.out.println("Entry: "+name);
if (name.equals("tmp/c")) {
byte[] bytes = zipStream.readAllBytes();
String s = new String(bytes);
System.out.println(s);
}
}
}
method readAllBytes seems weird, while we're in processing of stream, but it seems to work, I tested it also on some images, where there is higher chance of failure. So it's probably just unintuitive api, but it seems to work.
I am trying to Compare last modified date of two excel files and replace the old file with new file.
In Scenario : When there is no file in the first place, so the code copies the file to that location and later reads it.
Issue is : It throws a FileNotFound exception when the excel file is not present on the server,even after writing the file to the
server(via code),but the file is not seen on the server. It works on
my machine(windows),but fails when deployed on server.
Again, it works like charm when the file is present on the server,while the old is being replaced by the new file.
Can you please help and explain on why its failing in the above scenario,and only on server ?
if(row.getValue("fileType").toString().equals("xlsx")&&checkindatefolder.after(localdate))
{
messagelist.add("we are going to get the replace file in the server");
InputStream inp=folder.getFile();
ZipInputStream izs = new ZipInputStream(inp);
ZipEntry e = null;
while ((e = izs.getNextEntry()) != null) {
System.out.println("e.isDirectory(): "+e.isDirectory());
if (!e.isDirectory()) {
filename=e.getName();
System.out.println("filename: "+filename);
FileOutputStream os=new FileOutputStream("path"+e.getName());
byte[] buffer = new byte[4096];
int read=0;
System.out.println("writing to file");
while ((read=izs.read(buffer))> 0) {
System.out.println("1111");
os.write(buffer,0,read);
}
System.out.println("writing to file complete");
inp.close();
os.flush();
os.close();
}
}
Do all parts of the path exist?
So in your example:
/u01/app/webapps/out/pj/Create.xlsx
Do all subdirectories exist?
/u01/app/webapps/out/pj
If not, than trying to write there might fail with a FileNotFoundException.
You should create the directories with Files.creatDirectories(Path) first.
Hi I'm new to android programming.
I'm trying to create a program to unzip a zipped file in my sd card and I noticed something when I debug.
public void testZipOrder() throws Exception {
File file = new File(_zipFile);
zis = new ZipInputStream(new FileInputStream(file));
ZipEntry entry = null;
while ( (entry = zis.getNextEntry()) != null ) {
System.out.println( entry.getName());
}
}
}
this give me an output of :
06-27 00:42:06.360: I/System.out(15402): weee.txt
06-27 00:42:06.360: I/System.out(15402): hi/bye.txt
06-27 00:42:06.360: I/System.out(15402): hi/hiwayne.txt
isn't it suppose to give
weee.txt
hi/
hi/bye.txt
hi/hiwayne.txt
or something that displays its folder instead?
I tried this on my own environment using a test zip file created with 7zip and the following method:
public void testZipOrder() throws Exception {
File file = new File("zip.zip");
ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
ZipEntry entry = null;
while ( (entry = zis.getNextEntry()) != null ) {
System.out.println( entry.getName());
}
zis.close();
}
Note this method is effectively identical to yours.
The resulting output was:
file1.txt
folder1/
folder1/file2.txt
folder1/folder2/
folder1/folder2/file3.txt
Which is, I believe, what you are looking for. As such I expect the problem is with the zip file itself, not your code. It is likely that your zip file does not contain an entry for the directory "hi/".
See here for a basic description of how zip files are structured.
ZIP spec does not require the ordered "placement" of the file and its parent(s) directory in the zip file, and in fact the parent directory entries can be totally absent
See https://bugs.openjdk.java.net/browse/JDK-8054027
I can't seem to import the packages needed or find any online examples of how to extract a .tar.gz file in java.
What makes it worse is I'm using JSP pages and am having trouble importing packages into my project. I'm copying the .jar's into WebContent/WEB-INF/lib/ and then right clicking on the project and selecting import external jar and importing it. Sometimes the packages resolve, other times they don't. Can't seem to get GZIP to import either. The imports in eclipse for jsp aren't intuitive like they are in normal Java code where you can right click a recognized package and select import.
I've tried the Apache commons library, the ice and another one called JTar. Ice has imported, but I can't find any examples of how to use it?
I guess I need to uncompress the gzipped part first, then open it with the tarstream?
Any help is greatly appreciated.
The accepted answer works fine, but I think it is redundant to have a write to file operation.
You could use something like
TarArchiveInputStream tarInput =
new TarArchiveInputStream(new GZipInputStream(new FileInputStream("Your file name")));
TarArchiveEntry currentEntry = tarInput.getNextTarEntry();
while(currentEntry != null) {
File f = currentEntry.getFile();
// TODO write to file as usual
}
Hope this help.
Maven Repo
Ok, i finally figured this out, here is my code in case this helps anyone in the future.
Its written in Java, using the apache commons io and compress librarys.
File dir = new File("directory/of/.tar.gz/files/here");
File listDir[] = dir.listFiles();
if (listDir.length!=0){
for (File i:listDir){
/* Warning! this will try and extract all files in the directory
if other files exist, a for loop needs to go here to check that
the file (i) is an archive file before proceeding */
if (i.isDirectory()){
break;
}
String fileName = i.toString();
String tarFileName = fileName +".tar";
FileInputStream instream= new FileInputStream(fileName);
GZIPInputStream ginstream =new GZIPInputStream(instream);
FileOutputStream outstream = new FileOutputStream(tarFileName);
byte[] buf = new byte[1024];
int len;
while ((len = ginstream.read(buf)) > 0)
{
outstream.write(buf, 0, len);
}
ginstream.close();
outstream.close();
//There should now be tar files in the directory
//extract specific files from tar
TarArchiveInputStream myTarFile=new TarArchiveInputStream(new FileInputStream(tarFileName));
TarArchiveEntry entry = null;
int offset;
FileOutputStream outputFile=null;
//read every single entry in TAR file
while ((entry = myTarFile.getNextTarEntry()) != null) {
//the following two lines remove the .tar.gz extension for the folder name
String fileName = i.getName().substring(0, i.getName().lastIndexOf('.'));
fileName = fileName.substring(0, fileName.lastIndexOf('.'));
File outputDir = new File(i.getParent() + "/" + fileName + "/" + entry.getName());
if(! outputDir.getParentFile().exists()){
outputDir.getParentFile().mkdirs();
}
//if the entry in the tar is a directory, it needs to be created, only files can be extracted
if(entry.isDirectory){
outputDir.mkdirs();
}else{
byte[] content = new byte[(int) entry.getSize()];
offset=0;
myTarFile.read(content, offset, content.length - offset);
outputFile=new FileOutputStream(outputDir);
IOUtils.write(content,outputFile);
outputFile.close();
}
}
//close and delete the tar files, leaving the original .tar.gz and the extracted folders
myTarFile.close();
File tarFile = new File(tarFileName);
tarFile.delete();
}
}
I am trying to unzip a zip file which is stored in the raw folder. Code is as follows
try
{
File myDir = new File(getFilesDir().getAbsolutePath());
File newFile = new File(myDir + "/imageFolder");
if(!newFile.exists())
{
newFile.mkdir();
}
ZipInputStream zipIs = new ZipInputStream(con
.getResources().openRawResource(R.raw.images));
ZipEntry ze = null;
while ((ze = zipIs.getNextEntry()) != null)
{
Log.v("Name", ze.getName());
Log.v("Size", "" + ze.getSize());
if(ze.getSize() >0)
{
FileOutputStream fout = new FileOutputStream(newFile
+ "/" + ze.getName());
byte[] buffer = new byte[1024];
int length = 0;
while ((length = zipIs.read(buffer)) > 0)
{
fout.write(buffer, 0, length);
}
zipIs.closeEntry();
fout.close();
}
}
zipIs.close();
} catch (Exception e)
{
e.printStackTrace();
}
But I keep getting this error
01-18 11:24:28.301: W/System.err(2285): java.io.FileNotFoundException:
/data/data/com.example.ziptests/files/imageFolder/TestImages/background.png
(Not a directory)
I have absolutely no idea why it is causing this, it finds the files, but when it comes to writing them out, it brings up that error. Originally I found a problem that was caused by having the zip file zipped up on the mac, so I zipped up the file on my windows machine instead, that got rid of one problem (when you zip on a mac, it adds these extra folders and files such s store.ds which causes an error when trying to unzip), but this not a directory error keeps coming up.
Any ideas why this is happening?
Please try below link code for unzip zip file.
Code for Extract Zip File
Unzip Zip File
The Problem is I am Uploading zip File which is not made using winrar software, so it is not proper extracted and give me error.
It will solve your problem.
You can't write files to the raw folder. It is a read only dir intended to contain resource files included in your apk.
UPDATE
That file would be better in the assets directory. You can access it through the AssetManager. If not, leave it in the res/raw dir, but access it through Resources.openRawResource. Either way they are Read-Only.