优化
This commit is contained in:
@@ -4,6 +4,8 @@ import android.net.Uri
|
|||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import cn.hutool.core.codec.Base64
|
import cn.hutool.core.codec.Base64
|
||||||
import cn.hutool.core.util.HexUtil
|
import cn.hutool.core.util.HexUtil
|
||||||
|
import com.github.junrar.Archive
|
||||||
|
import com.github.junrar.rarfile.FileHeader
|
||||||
import io.legado.app.constant.AppConst
|
import io.legado.app.constant.AppConst
|
||||||
import io.legado.app.constant.AppConst.dateFormat
|
import io.legado.app.constant.AppConst.dateFormat
|
||||||
import io.legado.app.constant.AppLog
|
import io.legado.app.constant.AppLog
|
||||||
@@ -21,6 +23,10 @@ import io.legado.app.utils.*
|
|||||||
import kotlinx.coroutines.Dispatchers.IO
|
import kotlinx.coroutines.Dispatchers.IO
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import okio.use
|
||||||
|
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry
|
||||||
|
import org.apache.commons.compress.archivers.sevenz.SevenZFile
|
||||||
|
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel
|
||||||
import org.jsoup.Connection
|
import org.jsoup.Connection
|
||||||
import org.jsoup.Jsoup
|
import org.jsoup.Jsoup
|
||||||
import splitties.init.appCtx
|
import splitties.init.appCtx
|
||||||
@@ -312,21 +318,21 @@ interface JsExtensions : JsEncodeUtils {
|
|||||||
}
|
}
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Str转ByteArray */
|
/* Str转ByteArray */
|
||||||
fun strToBytes(str: String): ByteArray {
|
fun strToBytes(str: String): ByteArray {
|
||||||
return str.toByteArray(charset("UTF-8"))
|
return str.toByteArray(charset("UTF-8"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun strToBytes(str: String, charset: String): ByteArray {
|
fun strToBytes(str: String, charset: String): ByteArray {
|
||||||
return str.toByteArray(charset(charset))
|
return str.toByteArray(charset(charset))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ByteArray转Str */
|
/* ByteArray转Str */
|
||||||
fun bytesToStr(bytes: ByteArray): String {
|
fun bytesToStr(bytes: ByteArray): String {
|
||||||
return String(bytes, charset("UTF-8"))
|
return String(bytes, charset("UTF-8"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bytesToStr(bytes: ByteArray, charset: String): String {
|
fun bytesToStr(bytes: ByteArray, charset: String): String {
|
||||||
return String(bytes, charset(charset))
|
return String(bytes, charset(charset))
|
||||||
}
|
}
|
||||||
@@ -337,7 +343,7 @@ interface JsExtensions : JsEncodeUtils {
|
|||||||
fun base64Decode(str: String?): String {
|
fun base64Decode(str: String?): String {
|
||||||
return Base64.decodeStr(str)
|
return Base64.decodeStr(str)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun base64Decode(str: String?, charset: String): String {
|
fun base64Decode(str: String?, charset: String): String {
|
||||||
return Base64.decodeStr(str, charset(charset))
|
return Base64.decodeStr(str, charset(charset))
|
||||||
}
|
}
|
||||||
@@ -481,7 +487,7 @@ interface JsExtensions : JsEncodeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* js实现压缩文件解压
|
* js实现Zip压缩文件解压
|
||||||
* @param zipPath 相对路径
|
* @param zipPath 相对路径
|
||||||
* @return 相对路径
|
* @return 相对路径
|
||||||
*/
|
*/
|
||||||
@@ -497,6 +503,71 @@ interface JsExtensions : JsEncodeUtils {
|
|||||||
FileUtils.delete(zipFile.absolutePath)
|
FileUtils.delete(zipFile.absolutePath)
|
||||||
return unzipPath.substring(FileUtils.getCachePath().length)
|
return unzipPath.substring(FileUtils.getCachePath().length)
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* js实现7Zip压缩文件解压
|
||||||
|
* @param zipPath 相对路径
|
||||||
|
* @return 相对路径
|
||||||
|
*/
|
||||||
|
fun un7zFile(zipPath: String): String {
|
||||||
|
if (zipPath.isEmpty()) return ""
|
||||||
|
val unzipPath = FileUtils.getPath(
|
||||||
|
FileUtils.createFolderIfNotExist(FileUtils.getCachePath()),
|
||||||
|
FileUtils.getNameExcludeExtension(zipPath)
|
||||||
|
)
|
||||||
|
val unzipFolder = File(unzipPath).createFolderReplace()
|
||||||
|
val zipFile = getFile(zipPath)
|
||||||
|
SevenZipUtils.un7zToPath(zipFile, unzipFolder)
|
||||||
|
FileUtils.delete(zipFile.absolutePath)
|
||||||
|
return unzipPath.substring(FileUtils.getCachePath().length)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* js实现Rar压缩文件解压
|
||||||
|
* @param zipPath 相对路径
|
||||||
|
* @return 相对路径
|
||||||
|
*/
|
||||||
|
fun unrarFile(zipPath: String): String {
|
||||||
|
if (zipPath.isEmpty()) return ""
|
||||||
|
val unzipPath = FileUtils.getPath(
|
||||||
|
FileUtils.createFolderIfNotExist(FileUtils.getCachePath()),
|
||||||
|
FileUtils.getNameExcludeExtension(zipPath)
|
||||||
|
)
|
||||||
|
val unzipFolder = File(unzipPath).createFolderReplace()
|
||||||
|
val zipFile = getFile(zipPath)
|
||||||
|
RarUtils.unRarToPath(zipFile, unzipFolder)
|
||||||
|
FileUtils.delete(zipFile.absolutePath)
|
||||||
|
return unzipPath.substring(FileUtils.getCachePath().length)
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* js实现压缩文件解压
|
||||||
|
* @param zipPath 相对路径
|
||||||
|
* @return 相对路径
|
||||||
|
*/
|
||||||
|
fun unArchiveFile(zipPath: String): String {
|
||||||
|
if (zipPath.isEmpty()) return ""
|
||||||
|
val unzipPath = FileUtils.getPath(
|
||||||
|
FileUtils.createFolderIfNotExist(FileUtils.getCachePath()),
|
||||||
|
FileUtils.getNameExcludeExtension(zipPath)
|
||||||
|
)
|
||||||
|
val unzipFolder = File(unzipPath).createFolderReplace()
|
||||||
|
val zipFile = getFile(zipPath)
|
||||||
|
when {
|
||||||
|
zipPath.endsWith(".zip", ignoreCase = true) -> {
|
||||||
|
ZipUtils.unzipFile(zipFile, unzipFolder)
|
||||||
|
}
|
||||||
|
zipPath.endsWith(".rar", ignoreCase = true) -> {
|
||||||
|
RarUtils.unRarToPath(zipFile, unzipFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
zipPath.endsWith(".7z", ignoreCase = true) -> {
|
||||||
|
SevenZipUtils.un7zToPath(zipFile, unzipFolder)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
log("自动解压未识别类型${zipPath}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FileUtils.delete(zipFile.absolutePath)
|
||||||
|
return unzipPath.substring(FileUtils.getCachePath().length)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* js实现文件夹内所有文本文件读取
|
* js实现文件夹内所有文本文件读取
|
||||||
@@ -538,6 +609,40 @@ interface JsExtensions : JsEncodeUtils {
|
|||||||
return String(byteArray, Charset.forName(charsetName))
|
return String(byteArray, Charset.forName(charsetName))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取网络zip文件里面的数据
|
||||||
|
* @param url zip文件的链接或十六进制字符串
|
||||||
|
* @param path 所需获取文件在zip内的路径
|
||||||
|
* @return zip指定文件的数据
|
||||||
|
*/
|
||||||
|
fun getRarStringContent(url: String, path: String): String {
|
||||||
|
val byteArray = getRarByteArrayContent(url, path) ?: return ""
|
||||||
|
val charsetName = EncodingDetect.getEncode(byteArray)
|
||||||
|
return String(byteArray, Charset.forName(charsetName))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRarStringContent(url: String, path: String, charsetName: String): String {
|
||||||
|
val byteArray = getRarByteArrayContent(url, path) ?: return ""
|
||||||
|
return String(byteArray, Charset.forName(charsetName))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取网络7zip文件里面的数据
|
||||||
|
* @param url 7zip文件的链接或十六进制字符串
|
||||||
|
* @param path 所需获取文件在7zip内的路径
|
||||||
|
* @return zip指定文件的数据
|
||||||
|
*/
|
||||||
|
fun get7zStringContent(url: String, path: String): String {
|
||||||
|
val byteArray = get7zByteArrayContent(url, path) ?: return ""
|
||||||
|
val charsetName = EncodingDetect.getEncode(byteArray)
|
||||||
|
return String(byteArray, Charset.forName(charsetName))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun get7zStringContent(url: String, path: String, charsetName: String): String {
|
||||||
|
val byteArray = get7zByteArrayContent(url, path) ?: return ""
|
||||||
|
return String(byteArray, Charset.forName(charsetName))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取网络zip文件里面的数据
|
* 获取网络zip文件里面的数据
|
||||||
* @param url zip文件的链接或十六进制字符串
|
* @param url zip文件的链接或十六进制字符串
|
||||||
@@ -551,19 +656,75 @@ interface JsExtensions : JsEncodeUtils {
|
|||||||
HexUtil.decodeHex(url)
|
HexUtil.decodeHex(url)
|
||||||
}
|
}
|
||||||
val bos = ByteArrayOutputStream()
|
val bos = ByteArrayOutputStream()
|
||||||
val zis = ZipInputStream(ByteArrayInputStream(bytes))
|
ZipInputStream(ByteArrayInputStream(bytes)).use { zis ->
|
||||||
var entry: ZipEntry? = zis.nextEntry
|
var entry: ZipEntry
|
||||||
while (entry != null) {
|
while (zis.nextEntry.also { entry = it } != null) {
|
||||||
if (entry.name.equals(path)) {
|
if (entry.name.equals(path)) {
|
||||||
zis.use { it.copyTo(bos) }
|
zis.use { it.copyTo(bos) }
|
||||||
return bos.toByteArray()
|
return bos.toByteArray()
|
||||||
|
}
|
||||||
|
entry = zis.nextEntry
|
||||||
}
|
}
|
||||||
entry = zis.nextEntry
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log("getZipContent 未发现内容")
|
log("getZipContent 未发现内容")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取网络Rar文件里面的数据
|
||||||
|
* @param url Rar文件的链接或十六进制字符串
|
||||||
|
* @param path 所需获取文件在Rar内的路径
|
||||||
|
* @return Rar指定文件的数据
|
||||||
|
*/
|
||||||
|
fun getRarByteArrayContent(url: String, path: String): ByteArray? {
|
||||||
|
val bytes = if (url.isAbsUrl()) {
|
||||||
|
AnalyzeUrl(url, source = getSource()).getByteArray()
|
||||||
|
} else {
|
||||||
|
HexUtil.decodeHex(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bos = ByteArrayOutputStream()
|
||||||
|
Archive(ByteArrayInputStream(bytes)).use { archive ->
|
||||||
|
var entry: FileHeader
|
||||||
|
while (archive.nextFileHeader().also { entry = it } != null) {
|
||||||
|
if (entry.fileName.equals(path)) {
|
||||||
|
archive.getInputStream(entry).use { it.copyTo(bos) }
|
||||||
|
return bos.toByteArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("getRarContent 未发现内容")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取网络7zip文件里面的数据
|
||||||
|
* @param url 7zip文件的链接或十六进制字符串
|
||||||
|
* @param path 所需获取文件在7zip内的路径
|
||||||
|
* @return 7zip指定文件的数据
|
||||||
|
*/
|
||||||
|
fun get7zByteArrayContent(url: String, path: String): ByteArray? {
|
||||||
|
val bytes = if (url.isAbsUrl()) {
|
||||||
|
AnalyzeUrl(url, source = getSource()).getByteArray()
|
||||||
|
} else {
|
||||||
|
HexUtil.decodeHex(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
val bos = ByteArrayOutputStream()
|
||||||
|
SevenZFile(SeekableInMemoryByteChannel(bytes)).use { sevenZFile ->
|
||||||
|
var entry: SevenZArchiveEntry
|
||||||
|
while (sevenZFile.nextEntry.also { entry = it } != null) {
|
||||||
|
if (entry.name.equals(path)) {
|
||||||
|
sevenZFile.getInputStream(entry).use { it.copyTo(bos) }
|
||||||
|
return bos.toByteArray()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("get7zContent 未发现内容")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//******************文件操作************************//
|
//******************文件操作************************//
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,44 @@
|
|||||||
package io.legado.app.utils
|
package io.legado.app.utils
|
||||||
|
|
||||||
|
import androidx.annotation.Keep
|
||||||
import com.github.junrar.Archive
|
import com.github.junrar.Archive
|
||||||
import com.github.junrar.rarfile.FileHeader
|
import com.github.junrar.rarfile.FileHeader
|
||||||
|
import java.io.ByteArrayInputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@Suppress("unused")
|
|
||||||
|
@Keep
|
||||||
|
@Suppress("unused","MemberVisibilityCanBePrivate")
|
||||||
object RarUtils {
|
object RarUtils {
|
||||||
fun unRarToPath(inputStream: InputStream, path: String){
|
fun unRarToPath(inputStream: InputStream, destDir: File?) {
|
||||||
val archive= Archive(inputStream)
|
Archive(inputStream).use {
|
||||||
|
unRarToPath(it, destDir)
|
||||||
|
}
|
||||||
|
inputStream.close()
|
||||||
|
}
|
||||||
|
fun unRarToPath(byteArray: ByteArray, destDir: File?) {
|
||||||
|
Archive(ByteArrayInputStream(byteArray)).use {
|
||||||
|
unRarToPath(it, destDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unRarToPath(filePath:String, destDir: File?) {
|
||||||
|
Archive(File(filePath)).use {
|
||||||
|
unRarToPath(it, destDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unRarToPath(file: File, destDir: File?) {
|
||||||
|
Archive(file).use {
|
||||||
|
unRarToPath(it, destDir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unRarToPath(archive: Archive, destDir: File?) {
|
||||||
var entry: FileHeader
|
var entry: FileHeader
|
||||||
while (archive.nextFileHeader().also { entry=it }!=null){
|
while (archive.nextFileHeader().also { entry = it } != null) {
|
||||||
val entryFile = File(path, entry.fileName)
|
val entryFile = File(destDir, entry.fileName)
|
||||||
if (entry.isDirectory) {
|
if (entry.isDirectory) {
|
||||||
if (!entryFile.exists()) {
|
if (!entryFile.exists()) {
|
||||||
entryFile.mkdirs()
|
entryFile.mkdirs()
|
||||||
@@ -31,7 +58,6 @@ object RarUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
inputStream.close()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ package io.legado.app.utils
|
|||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.ParcelFileDescriptor
|
import android.os.ParcelFileDescriptor
|
||||||
|
import androidx.annotation.Keep
|
||||||
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry
|
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry
|
||||||
import org.apache.commons.compress.archivers.sevenz.SevenZFile
|
import org.apache.commons.compress.archivers.sevenz.SevenZFile
|
||||||
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel
|
import org.apache.commons.compress.utils.SeekableInMemoryByteChannel
|
||||||
@@ -9,30 +10,38 @@ import java.io.File
|
|||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.nio.channels.FileChannel
|
import java.nio.channels.FileChannel
|
||||||
@Suppress("unused")
|
|
||||||
|
@Keep
|
||||||
|
@Suppress("unused","MemberVisibilityCanBePrivate")
|
||||||
object SevenZipUtils {
|
object SevenZipUtils {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fun un7zToPath(inputStream: InputStream, path: String){
|
fun un7zToPath(inputStream: InputStream, destDir: File?){
|
||||||
un7zToPath(SevenZFile(SeekableInMemoryByteChannel(inputStream.readBytes())),path)
|
un7zToPath(SevenZFile(SeekableInMemoryByteChannel(inputStream.readBytes())),destDir)
|
||||||
}
|
}
|
||||||
fun un7zToPath(pfd: ParcelFileDescriptor, path: String){
|
fun un7zToPath(byteArray: ByteArray, destDir: File?){
|
||||||
un7zToPath(SevenZFile(ParcelFileDescriptorChannel(pfd)),path)
|
un7zToPath(SevenZFile(SeekableInMemoryByteChannel(byteArray)),destDir)
|
||||||
|
}
|
||||||
|
fun un7zToPath(pfd: ParcelFileDescriptor, destDir: File?){
|
||||||
|
un7zToPath(SevenZFile(ParcelFileDescriptorChannel(pfd)),destDir)
|
||||||
}
|
}
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
fun un7zToPath(fileChannel: FileChannel, path: String){
|
fun un7zToPath(fileChannel: FileChannel, destDir: File?){
|
||||||
un7zToPath(SevenZFile(fileChannel),path)
|
un7zToPath(SevenZFile(fileChannel),destDir)
|
||||||
}
|
}
|
||||||
fun un7zToPath(file: File, path: String){
|
fun un7zToPath(file: File, destDir: File?){
|
||||||
un7zToPath(SevenZFile(file),path)
|
un7zToPath(SevenZFile(file),destDir)
|
||||||
|
}
|
||||||
|
fun un7zToPath(filePath: String, destDir: File?){
|
||||||
|
un7zToPath(SevenZFile(File(filePath)),destDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun un7zToPath(sevenZFile:SevenZFile, path: String){
|
fun un7zToPath(sevenZFile:SevenZFile, destDir: File?){
|
||||||
var entry: SevenZArchiveEntry
|
var entry: SevenZArchiveEntry
|
||||||
while (sevenZFile.nextEntry.also { entry=it }!=null){
|
while (sevenZFile.nextEntry.also { entry=it }!=null){
|
||||||
val entryFile = File(path, entry.name)
|
val entryFile = File(destDir, entry.name)
|
||||||
if (entry.isDirectory) {
|
if (entry.isDirectory) {
|
||||||
if (!entryFile.exists()) {
|
if (!entryFile.exists()) {
|
||||||
entryFile.mkdirs()
|
entryFile.mkdirs()
|
||||||
|
|||||||
Reference in New Issue
Block a user