-->

J7zip on Android - Extracting From an Archive and

2020-06-23 06:10发布

问题:

My previous question got closed as not constructive. I edited it there, but didn't see that it was closed ):

I'm writing an application that involves extracting 7z archives. There doesn't seem to be any native support, so I've ventured off in search of third-party libraries or source code I could integrate into my project.

I have been trying to implement J7zip but have not been successful.

Listing contents of the archive returns no files:

12-24 13:36:44.216: I/System.out(18473): J7zip 4.43 ALPHA 2 (2 CPUs)
12-24 13:36:44.232: I/System.out(18473):   Date   Time   Attr         Size   Compressed  Name
12-24 13:36:44.232: I/System.out(18473): -------------- ----- ------------ ------------  ------------
12-24 13:36:44.240: I/System.out(18473): -------------- ----- ------------ ------------  ------------

However, listing the contents on windows (using 7z.exe) returns the following

7-Zip 9.22 beta  Copyright (c) 1999-2011 Igor Pavlov  2011-04-18

Listing archive: archive.7z

--
Path = archive.7z
Type = 7z
Method = LZMA
Solid = -
Blocks = 1
Physical Size = 183119
Headers Size = 122

   Date      Time    Attr         Size   Compressed  Name
------------------- ----- ------------ ------------  ------------------------
                    .....       524288       182997  contents.txt
------------------- ----- ------------ ------------  ------------------------
                                524288       182997  1 files, 0 folders

Extracting fails, I have the logcat of that here since it's a bit longer.

There seems to be an io problem here, but I'm suspecting something else since listing this archive returns no files.

Does anyone have experience extracting and listing archive contents using J7zip?

回答1:

There are a few possible solutions here.

I first started by trying to cross-compile the 7zip jbinding project. I installed the armeabi c and c++ compilers onto my machine and attempted to build the project. Unfortunately, I was unable to build a binary that could be used in an Android project. I mentioned the libraries that were causing trouble with trying to load the compiled jbinding binaries back in the forum post.

My next lead was implementing the java port of p7z, J7zip (http://sourceforge.net/projects/p7zip/files/J7Zip/). Implementing this wasn't too bad, except that I had to modify code where the j7z library would try to write to the root of the SD card (no root access). This port worked well for the most part, but would cause out of memory errors when extracting larger archives, or archives containing many similar files. The problem was the library was trying to allocate too much memory for the dictionary (it would allocate the size of all the extracted contents, even if you only wanted to extract one file). So this library would not work in my case, and I don't think it would support the compression you're working with.

And finally, I arrived at this seemingly dead Google Code project called andro7z (http://code.google.com/p/andro7z/). This code contains a version of 7zip and a very, very basic JNI implementation. When you first grab the source, all it can do is print usage but it gives you a good starting point. I ended up studying and modifying it so I could return an array of strings containing the names of the files contained within the archive, as well as extract specific or all files from an archive. Since I was only working with 7z files, I didn't make it a very elegant implementation, but it works. Using the actual 7zip c/cpp sources means that out streams are handled properly and won't try to allocate outrageous dictionary sizes.

To compile andro7z you'll need to grab the android NDK if you don't already have it. From there you're going to have to write your own JNI methods so you can interact with the native binaries using Java. You'll see some test arguments at the top of 7za.cpp, you'll be able to uncomment those and test a hard-coded extraction.