Skip to content

Commit 1455a26

Browse files
committed
wip: compressing .7z & .tar.gz
1 parent 3661a4d commit 1455a26

File tree

5 files changed

+97
-14
lines changed

5 files changed

+97
-14
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ dependencies {
9494
implementation(libs.androidx.swiperefreshlayout)
9595
implementation(libs.androidpdfviewer)
9696
implementation(libs.apache.commons.compress)
97+
implementation(libs.tukaanixz)
9798
implementation(libs.roottools)
9899
implementation(libs.rootshell)
99100
implementation(libs.gestureviews)

app/src/main/kotlin/com/simplemobiletools/filemanager/pro/adapters/ItemsAdapter.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ class ItemsAdapter(
485485
activity.toast(R.string.compressing)
486486
val paths = getSelectedFileDirItems().map { it.path }
487487
ensureBackgroundThread {
488-
if (CompressionHelper.compressPaths(activity, paths, destination, compressionFormat, password)) {
488+
if (CompressionHelper.compress(activity, paths, destination, compressionFormat, password)) {
489489
activity.runOnUiThread {
490490
activity.toast(R.string.compression_successful)
491491
listener?.refreshFragment()

app/src/main/kotlin/com/simplemobiletools/filemanager/pro/helpers/CompressionFormat.kt

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package com.simplemobiletools.filemanager.pro.helpers
22

3-
enum class CompressionFormat(val extension: String) {
4-
ZIP(".zip"),
5-
SEVEN_ZIP(".7z"),
6-
TAR_DEFLATE(".tar.deflate"),
7-
TAR_GZ(".tar.gz"),
8-
TAR_SZ(".tar.sz"),
9-
TAR_XZ(".tar.xz");
3+
enum class CompressionFormat(val extension: String, val canReadEncryptedArchive: Boolean, val canCreateEncryptedArchive: Boolean) {
4+
ZIP(".zip", true, true),
5+
SEVEN_ZIP(".7z", true, false),
6+
TAR_DEFLATE(".tar.deflate", false, false),
7+
TAR_GZ(".tar.gz", false, false),
8+
TAR_SZ(".tar.sz", false, false),
9+
TAR_XZ(".tar.xz", false, false);
1010

1111
companion object {
1212
fun fromExtension(extension: String): CompressionFormat {

app/src/main/kotlin/com/simplemobiletools/filemanager/pro/helpers/CompressionHelper.kt

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,24 @@ import com.simplemobiletools.commons.extensions.*
55
import net.lingala.zip4j.io.outputstream.ZipOutputStream
66
import net.lingala.zip4j.model.ZipParameters
77
import net.lingala.zip4j.model.enums.EncryptionMethod
8+
import org.apache.commons.compress.archivers.sevenz.SevenZOutputFile
9+
import org.apache.commons.compress.archivers.tar.TarArchiveEntry
10+
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream
11+
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream
12+
import org.apache.commons.compress.utils.IOUtils
813
import java.io.Closeable
914
import java.io.File
15+
import java.io.FileInputStream
16+
import java.io.IOException
17+
import java.nio.file.Files
18+
import java.nio.file.Path
1019
import java.util.LinkedList
1120

21+
1222
class CompressionHelper {
1323

1424
companion object {
15-
fun compressPaths(
25+
fun compress(
1626
activity: BaseSimpleActivity,
1727
sourcePaths: List<String>,
1828
targetPath: String,
@@ -21,7 +31,7 @@ class CompressionHelper {
2131
): Boolean {
2232
return when (compressionFormat) {
2333
CompressionFormat.ZIP -> compressToZip(activity, sourcePaths, targetPath, password)
24-
CompressionFormat.SEVEN_ZIP -> compressToSevenZip(activity, sourcePaths, targetPath, password)
34+
CompressionFormat.SEVEN_ZIP -> compressToSevenZip(activity, sourcePaths, targetPath)
2535
CompressionFormat.TAR_DEFLATE -> compressToTarDeflate(activity, sourcePaths, targetPath, password)
2636
CompressionFormat.TAR_GZ -> compressToTarGz(activity, sourcePaths, targetPath, password)
2737
CompressionFormat.TAR_SZ -> compressToTarSz(activity, sourcePaths, targetPath, password)
@@ -120,11 +130,34 @@ class CompressionHelper {
120130
activity: BaseSimpleActivity,
121131
sourcePaths: List<String>,
122132
targetPath: String,
123-
password: String? = null
124133
): Boolean {
125-
return false
134+
try {
135+
SevenZOutputFile(File(targetPath)).use { sevenZOutput ->
136+
sourcePaths.forEach { sourcePath ->
137+
Files.walk(File(sourcePath).toPath()).forEach { path ->
138+
val file = path.toFile()
139+
140+
if (!activity.getIsPathDirectory(file.absolutePath)) {
141+
FileInputStream(file).use { _ ->
142+
val sevenZArchiveEntry = sevenZOutput.createArchiveEntry(file, file.toString())
143+
sevenZOutput.putArchiveEntry(sevenZArchiveEntry)
144+
sevenZOutput.write(Files.readAllBytes(file.toPath()))
145+
sevenZOutput.closeArchiveEntry()
146+
}
147+
}
148+
}
149+
}
150+
151+
sevenZOutput.finish()
152+
}
153+
} catch (e: IOException) {
154+
e.printStackTrace()
155+
return false
156+
}
157+
return true
126158
}
127159

160+
128161
private fun compressToTarDeflate(
129162
activity: BaseSimpleActivity,
130163
sourcePaths: List<String>,
@@ -140,7 +173,27 @@ class CompressionHelper {
140173
targetPath: String,
141174
password: String? = null
142175
): Boolean {
143-
return false
176+
val tarPath = targetPath.replace(CompressionFormat.TAR_GZ.extension, ".tar")
177+
val tarCreated = createTar(activity, sourcePaths, tarPath)
178+
179+
if (tarCreated) {
180+
val tarFile = File(tarPath)
181+
val fos = activity.getFileOutputStreamSync(targetPath, "application/gzip")
182+
try {
183+
GzipCompressorOutputStream(fos).use { gzipOutput ->
184+
gzipOutput.write(Files.readAllBytes(tarFile.toPath()))
185+
gzipOutput.finish()
186+
}
187+
} catch (e: IOException) {
188+
e.printStackTrace()
189+
return false
190+
} finally {
191+
tarFile.delete()
192+
}
193+
return true
194+
} else {
195+
return false
196+
}
144197
}
145198

146199
private fun compressToTarSz(
@@ -160,5 +213,32 @@ class CompressionHelper {
160213
): Boolean {
161214
return false
162215
}
216+
217+
private fun createTar(activity: BaseSimpleActivity, sourcePaths: List<String>, targetPath: String): Boolean {
218+
val fos = activity.getFileOutputStreamSync(targetPath, "application/x-tar")
219+
try {
220+
TarArchiveOutputStream(fos).use { archive ->
221+
sourcePaths.forEach { sourcePath ->
222+
Files.walk(File(sourcePath).toPath()).forEach { path: Path ->
223+
val file = path.toFile()
224+
225+
if (!activity.getIsPathDirectory(file.absolutePath)) {
226+
val tarArchiveEntry = TarArchiveEntry(file, file.toString())
227+
FileInputStream(file).use { fis ->
228+
archive.putArchiveEntry(tarArchiveEntry)
229+
IOUtils.copy(fis, archive)
230+
archive.closeArchiveEntry()
231+
}
232+
}
233+
}
234+
}
235+
archive.finish()
236+
}
237+
} catch (e: IOException) {
238+
e.printStackTrace()
239+
return false
240+
}
241+
return true
242+
}
163243
}
164244
}

gradle/libs.versions.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ rootshell = "1.6"
1414
roottools = "df729dcb13"
1515
zip4j = "2.11.5"
1616
apachecommonscompress = "1.22"
17+
tukaanixz = "1.9"
1718
#Gradle
1819
gradlePlugins-agp = "8.1.0"
1920
#build
2021
app-build-compileSDKVersion = "34"
2122
app-build-targetSDK = "34"
22-
app-build-minimumSDK = "23"
23+
app-build-minimumSDK = "26"
2324
app-build-javaVersion = "VERSION_17"
2425
app-build-kotlinJVMTarget = "17"
2526
#versioning
@@ -40,6 +41,7 @@ rootshell = { module = "com.github.Stericson:RootShell", version.ref = "rootshel
4041
roottools = { module = "com.github.Stericson:RootTools", version.ref = "roottools" }
4142
zip4j = { module = "net.lingala.zip4j:zip4j", version.ref = "zip4j" }
4243
apache-commons-compress = { module = "org.apache.commons:commons-compress", version.ref = "apachecommonscompress" }
44+
tukaanixz = { module = "org.tukaani:xz", version.ref = "tukaanixz" }
4345
[plugins]
4446
android = { id = "com.android.application", version.ref = "gradlePlugins-agp" }
4547
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }

0 commit comments

Comments
 (0)