omicronapps / 7-Zip-JBinding-4Android

Android Java wrapper for 7z archiver engine
GNU Lesser General Public License v2.1
121 stars 24 forks source link

A Request... Multipart RAR #32

Closed WirelessAlien closed 10 months ago

WirelessAlien commented 10 months ago

First of all thank you for this project. This is not an issue... I just wanted to ask you to look at this code, when you can manage time. I am trying to extract multipart rar but it is showing this error -

Error: HRESULT: 0x1 (FALSE). Archive file (format: Rar) can't be opened net.sf.sevenzipjbinding.SevenZipException: HRESULT: 0x1 (FALSE). Archive file (format: Rar) can't be opened at net.sf.sevenzipjbinding.SevenZip.nativeOpenArchive(Native Method) at net.sf.sevenzipjbinding.SevenZip.callNativeOpenArchive(SevenZip.java:946) at net.sf.sevenzipjbinding.SevenZip.openInArchive(SevenZip.java:836) at com.wirelessalien.zipxtract.ExtractFragment$pickFilesLauncher$1$1.invokeSuspend(ExtractFragment.kt:109) at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33) at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106) at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42) at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95) at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:749) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677) at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664) Caused by: kotlin.NotImplementedError: An operation is not implemented: Not yet implemented at com.wirelessalien.zipxtract.ArchiveOpenVolumeCallback.seek(ArchiveOpenMultipartCallback.kt:100)

 for (tempFile in tempFiles) {
                        val archiveOpenVolumeCallback = ArchiveOpenVolumeCallback()
                        val inStream: IInStream? = archiveOpenVolumeCallback.getStream(tempFile.absolutePath)
                        val inArchive: IInArchive = SevenZip.openInArchive(ArchiveFormat.RAR, inStream, archiveOpenVolumeCallback)

                        try {
                            val itemCount = inArchive.numberOfItems
                            for (i in 0 until itemCount) {
                                val path = inArchive.getProperty(i, PropID.PATH) as String
                                val file = File(requireContext().cacheDir, path)
                                inArchive.extract(intArrayOf(i), false, ExtractCallback(file))
                            }
                        } finally {
                            inArchive.close()
                            archiveOpenVolumeCallback.close()
                        }
                    }

Callback class -

 class ArchiveOpenVolumeCallback : IArchiveOpenVolumeCallback, IArchiveOpenCallback {
 private val openedRandomAccessFileList = HashMap<String, RandomAccessFile>()
 private var name: String? = null

@Throws(SevenZipException::class)
override fun getProperty(propID: PropID): Any? {
    return if (propID == PropID.NAME) name else null
}

@Throws(SevenZipException::class)
override fun getStream(filename: String): IInStream? {
    return try {
        var randomAccessFile = openedRandomAccessFileList[filename]
        if (randomAccessFile != null) { // Cache hit.
            randomAccessFile.seek(0)
            name = filename
            RandomAccessFileInStream(randomAccessFile)
        } else {
            randomAccessFile = RandomAccessFile(filename, "r")
            openedRandomAccessFileList[filename] = randomAccessFile
            name = filename
            RandomAccessFileInStream(randomAccessFile)
        }
    } catch (e: FileNotFoundException) {
        null
    } catch (e: Exception) {
        throw RuntimeException(e)
    }
}

@Throws(IOException::class)
fun close() {
    for (file in openedRandomAccessFileList.values) {
        file.close()
    }
}

@Throws(SevenZipException::class)
override fun setCompleted(files: Long?, bytes: Long?) {}

@Throws(SevenZipException::class)
override fun setTotal(files: Long?, bytes: Long?) {}

}

class ExtractCallback(private val file: File) : IArchiveExtractCallback {
private var outputStream: OutputStream? = null

@Throws(SevenZipException::class)
override fun setTotal(total: Long) {}

@Throws(SevenZipException::class)
override fun setCompleted(completeValue: Long) {}

@Throws(SevenZipException::class)
override fun getStream(index: Int, extractAskMode: ExtractAskMode): ISequentialOutStream? {
    return if (extractAskMode != ExtractAskMode.EXTRACT) null else object : ISequentialOutStream {
        @Throws(SevenZipException::class)
        override fun write(data: ByteArray): Int {
            try {
                if (outputStream == null) {
                    file.parentFile?.mkdirs()
                    outputStream = FileOutputStream(file)
                }
                outputStream!!.write(data)
                return data.size
            } catch (e: IOException) {
                throw SevenZipException(e)
            }
        }
    }
}

@Throws(SevenZipException::class)
override fun prepareOperation(extractAskMode: ExtractAskMode) {}

@Throws(SevenZipException::class)
override fun setOperationResult(extractOperationResult: ExtractOperationResult) {
    try {
        outputStream?.close()
        outputStream = null
    } catch (e: IOException) {
        throw SevenZipException(e)
    }
}

}

WirelessAlien commented 10 months ago

I fixed it.

zhusy0627 commented 2 months ago

can you tell how fixed, thx

WirelessAlien commented 2 months ago

can you tell how fixed, thx

I actually forgot what was the issue here but If I am not mistaken the issue was that I was using ArchiveFormat.RAR to extract RAR5, need to use ArchiveFormat.RAR5 to extract RAR5 file or don't specify the archiveformat, just define like - private var archiveFormat: ArchiveFormat? = null and let the library decide the archive format. you can check working example on - https://github.com/WirelessAlien/ZipXtract