初步实现RAR,7ZIP解压

This commit is contained in:
ag2s20150909 2023-03-12 20:41:37 +08:00
parent fe646575c0
commit f429924e8f
5 changed files with 177 additions and 1 deletions

View File

@ -135,7 +135,7 @@ android {
dependencies {
compileOnly "com.android.tools.build:gradle:$agp_version"
//noinspection GradleDependency,GradlePackageUpdate
coreLibraryDesugaring('com.android.tools:desugar_jdk_libs:2.0.2')
coreLibraryDesugaring('com.android.tools:desugar_jdk_libs_nio:2.0.2')
testImplementation('junit:junit:4.13.2')
androidTestImplementation('androidx.test:runner:1.5.2')
androidTestImplementation('androidx.test.espresso:espresso-core:3.5.1')
@ -231,6 +231,10 @@ dependencies {
//apache
implementation('org.apache.commons:commons-text:1.10.0')
implementation 'org.apache.commons:commons-compress:1.22'
//RAR
implementation 'com.github.junrar:junrar:7.5.4'
//MarkDown
def markwonVersion = "4.6.2"

View File

@ -564,6 +564,7 @@ interface JsExtensions : JsEncodeUtils {
return null
}
//******************文件操作************************//
/**

View File

@ -0,0 +1,79 @@
package io.legado.app.utils
import android.annotation.SuppressLint
import android.os.ParcelFileDescriptor
import android.system.ErrnoException
import android.system.Os
import android.system.OsConstants
import java.io.IOException
import java.nio.ByteBuffer
import java.nio.channels.SeekableByteChannel
@SuppressLint("NewApi")
class ParcelFileDescriptorChannel(private val pfd: ParcelFileDescriptor) : SeekableByteChannel {
@Throws(IOException::class)
override fun read(dst: ByteBuffer): Int {
return try {
Os.read(pfd.fileDescriptor, dst)
} catch (e: ErrnoException) {
throw RuntimeException(e)
}
}
@Throws(IOException::class)
override fun write(src: ByteBuffer): Int {
return try {
Os.write(pfd.fileDescriptor, src)
} catch (e: ErrnoException) {
throw RuntimeException(e)
}
}
@Throws(IOException::class)
override fun position(): Long {
return try {
Os.lseek(pfd.fileDescriptor, 0, OsConstants.SEEK_CUR)
} catch (e: ErrnoException) {
throw RuntimeException(e)
}
}
@Throws(IOException::class)
override fun position(newPosition: Long): SeekableByteChannel {
try {
Os.lseek(pfd.fileDescriptor, newPosition, OsConstants.SEEK_SET)
} catch (e: ErrnoException) {
throw RuntimeException(e)
}
return this
}
@Throws(IOException::class)
override fun size(): Long {
return try {
Os.fstat(pfd.fileDescriptor).st_size
} catch (e: ErrnoException) {
throw RuntimeException(e)
}
}
@Throws(IOException::class)
override fun truncate(newSize: Long): SeekableByteChannel {
require(!(newSize < 0L || newSize > Int.MAX_VALUE)) { "Size has to be in range 0.. " + Int.MAX_VALUE }
try {
Os.ftruncate(pfd.fileDescriptor, newSize)
} catch (e: ErrnoException) {
throw RuntimeException(e)
}
return this
}
override fun isOpen(): Boolean {
return pfd.fileDescriptor.valid()
}
@Throws(IOException::class)
override fun close() {
pfd.close()
}
}

View File

@ -0,0 +1,37 @@
package io.legado.app.utils
import com.github.junrar.Archive
import com.github.junrar.rarfile.FileHeader
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
@Suppress("unused")
object RarUtils {
fun unRarToPath(inputStream: InputStream, path: String){
val archive= Archive(inputStream)
var entry: FileHeader
while (archive.nextFileHeader().also { entry=it }!=null){
val entryFile = File(path, entry.fileName)
if (entry.isDirectory) {
if (!entryFile.exists()) {
entryFile.mkdirs()
}
continue
}
if (entryFile.parentFile?.exists() != true) {
entryFile.parentFile?.mkdirs()
}
if (!entryFile.exists()) {
entryFile.createNewFile()
entryFile.setReadable(true)
entryFile.setExecutable(true)
}
FileOutputStream(entryFile).use {
archive.getInputStream(entry).copyTo(it)
}
}
inputStream.close()
}
}

View File

@ -0,0 +1,55 @@
package io.legado.app.utils
import android.annotation.SuppressLint
import android.os.ParcelFileDescriptor
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry
import org.apache.commons.compress.archivers.sevenz.SevenZFile
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.nio.channels.FileChannel
@Suppress("unused")
object SevenZipUtils {
fun un7zToPath(inputStream: InputStream, path: String){
un7zToPath(SevenZFile(SeekableInMemoryByteChannel(inputStream.readBytes())),path)
}
fun un7zToPath(pfd: ParcelFileDescriptor, path: String){
un7zToPath(SevenZFile(ParcelFileDescriptorChannel(pfd)),path)
}
@SuppressLint("NewApi")
fun un7zToPath(fileChannel: FileChannel, path: String){
un7zToPath(SevenZFile(fileChannel),path)
}
fun un7zToPath(file: File, path: String){
un7zToPath(SevenZFile(file),path)
}
fun un7zToPath(sevenZFile:SevenZFile, path: String){
var entry: SevenZArchiveEntry
while (sevenZFile.nextEntry.also { entry=it }!=null){
val entryFile = File(path, entry.name)
if (entry.isDirectory) {
if (!entryFile.exists()) {
entryFile.mkdirs()
}
continue
}
if (entryFile.parentFile?.exists() != true) {
entryFile.parentFile?.mkdirs()
}
if (!entryFile.exists()) {
entryFile.createNewFile()
entryFile.setReadable(true)
entryFile.setExecutable(true)
}
FileOutputStream(entryFile).use {
sevenZFile.getInputStream(entry).copyTo(it)
}
}
}
}