0

I'm writing an Android application that need to extract 7z archives.Pressed for time,I've searching of third-party libraries or source code which can be used in my project.

i copy .so file in /libs folder

app\src\main\jniLibs\armeabi\libun7z.so

i cant extract 7z file in android

AndUn7z.extract7z(My7z, My7zPath);

after run this line i have this error :

java.lang.UnsatisfiedLinkError: No implementation found for int com.darkgamers.pepsiman.browser.mainmenu.AndUn7z.un7zip(java.lang.String, java.lang.String) (tried Java_com_darkgamers_pepsiman_browser_mainmenu_AndUn7z_un7zip and Java_com_darkgamers_pepsiman_browser_mainmenu_AndUn7z_un7zip__Ljava_lang_String_2Ljava_lang_String_2) at com.darkgamers.pepsiman.browser.mainmenu.AndUn7z.un7zip(Native Method)

this is my code :

public class AndUn7z {

public static boolean extract7z(String filePath, String outPath)
{
    File outDir = new File(outPath);
    if(!outDir.exists() || !outDir.isDirectory())
    {
        outDir.mkdirs();
    }
    return (AndUn7z.un7zip(filePath, outPath) == 1);
}

/**
 * Extract from assets
 * @param context
 * @param assetPath
 * @param outPath
 * @return
 * @throws Exception
 */
public static boolean extractAssets(Context context, String assetPath, String outPath)
{
    File outDir = new File(outPath);
    if(!outDir.exists() || !outDir.isDirectory())
    {
        outDir.mkdirs();
    }

    String tempPath = outPath + File.separator + ".temp";
    try {
        copyFromAssets(context, assetPath, tempPath);
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    boolean ret = (AndUn7z.un7zip(tempPath, outPath) == 1);
    new File(tempPath).delete();

    return ret;
}

/**
 * Copy asset to temp
 * @param context
 * @param assetPath
 * @param tempPath
 * @throws Exception
 */
private static void copyFromAssets(Context context, String assetPath, String tempPath)
        throws Exception
{
    InputStream inputStream = context.getAssets().open(assetPath);
    FileOutputStream fileOutputStream = new FileOutputStream(tempPath);
    int length = -1;
    byte[] buffer = new byte[0x400000];
    while ((length = inputStream.read(buffer)) != -1) {
        fileOutputStream.write(buffer, 0, length);
    }
    fileOutputStream.flush();
    fileOutputStream.close();
    inputStream.close();
}

//JNI interface
private static native int un7zip(String filePath, String outPath);

static {
    System.loadLibrary("un7z");
}

}

2 Answers2

1

Download the 7z SDK for Java and use reuse its LzmaAlone class as follows:

    BufferedInputStream inStream  = new BufferedInputStream(ourInputfile, BUFFER_SIZE);
    BufferedOutputStream outStream = new BufferedOutputStream(new FileOutputStream(ourOutputfile), BUFFER_SIZE);

    int propertiesSize = 5;
    byte[] properties = new byte[propertiesSize];

    if (inStream.read(properties, 0, propertiesSize) != propertiesSize)
        throw new IOException("input .lzma file is too short");

    Decoder decoder = new Decoder();

    if (!decoder.SetDecoderProperties(properties))
        throw new IllegalArgumentException("Incorrect stream properties");

    long outSize = 0;

    for (int i = 0; i < 8; i++)
    {
        int v = inStream.read();
        if (v < 0)
            throw new IOException("Can't read stream size");
        outSize |= ((long)v) << (8 * i);
    }

    if (!decoder.Code(inStream, outStream, outSize))
        throw new IOException("Error in data stream");

    outStream.flush();
    outStream.close();
    inStream.close();
ManuelTS
  • 316
  • 4
  • 14
0

After fundling around with 7z and knowing you asked for 7z, the Java API is much easier in xz:

XZInputStream in = new XZInputStream(your_input_stream_xz_compressed);
FileOutputStream out = new FileOutputStream(your_output_file_decompressed);
byte[] buffer = new byte[1024];
int length;

while ((length = in.read(buffer)) != -1) // Copy DB byte for bite
  out.write(buffer, 0, length);

out.flush();
out.close();
in.close();
ManuelTS
  • 316
  • 4
  • 14