使用操作系统工具进行压缩和解压,总会出现意料之外的问题,例如 mac 上的__MAXOS
的文件夹,windows中的中文文件名的编码问题,所以这类压缩文件最好使用代码去操作。
代码如下,测试时,可以使用build
文件夹辅助测试
class ZipUtil {
val TAG = "ZipUtil"
@Test
fun testZipFile() {
val f1 = File("./build/ziptest/中文.txt")
createFile(f1.path)
val f2 = File("./build/ziptest/2.txt")
createFile(f2.path)
val f3 = File("./build/ziptest/3.txt")
createFile(f3.path)
zip(listOf(f1, f2, f3), "./build/ziptest.zip")
val res = "./build/zipresult"
unzip("./build/ziptest.zip", res)
Assert.assertEquals(3, File(res).listFiles().size)
}
@Test
fun mp3Zip() {
val files = File("./build/douyin_music").listFiles().toList()
zip(files, "./build/douyin.zip")
unzip("./build/douyin.zip", "./build/douyin_res")
Assert.assertEquals(files.size, File("./build/douyin_res").listFiles().size)
}
/**
* https://www.jianshu.com/p/2adf4a4b1bd8
*/
fun unzip(zipFile: String, descDir: String) {
val buffer = ByteArray(1024)
var outputStream: OutputStream? = null
var inputStream: InputStream? = null
try {
val zf = ZipFile(zipFile)
val entries = zf.entries()
while (entries.hasMoreElements()) {
val zipEntry: ZipEntry = entries.nextElement() as ZipEntry
val zipEntryName: String = zipEntry.name
inputStream = zf.getInputStream(zipEntry)
val descFilePath: String = descDir + File.separator + zipEntryName
val descFile: File = createFile(descFilePath)
outputStream = FileOutputStream(descFile)
var len: Int
while (inputStream.read(buffer).also { len = it } > 0) {
outputStream.write(buffer, 0, len)
}
inputStream.closeQuietly()
outputStream.closeQuietly()
}
} finally {
inputStream?.closeQuietly()
outputStream?.closeQuietly()
}
}
private fun createFile(filePath: String): File {
val file = File(filePath)
val parentFile = file.parentFile!!
if (!parentFile.exists()) {
parentFile.mkdirs()
}
if (!file.exists()) {
file.createNewFile()
}
return file
}
fun zip(files: List<File>, zipFilePath: String) {
if (files.isEmpty()) return
val zipFile = createFile(zipFilePath)
val buffer = ByteArray(1024)
var zipOutputStream: ZipOutputStream? = null
var inputStream: FileInputStream? = null
try {
zipOutputStream = ZipOutputStream(FileOutputStream(zipFile))
for (file in files) {
if (!file.exists()) continue
zipOutputStream.putNextEntry(ZipEntry(file.name))
inputStream = FileInputStream(file)
var len: Int
while (inputStream.read(buffer).also { len = it } > 0) {
zipOutputStream.write(buffer, 0, len)
}
zipOutputStream.closeEntry()
}
} finally {
inputStream?.close()
zipOutputStream?.close()
}
}
fun zipByFolder(fileDir: String, zipFilePath: String) {
val folder = File(fileDir)
if (folder.exists() && folder.isDirectory) {
val files = folder.listFiles()
val filesList: List<File> = files.toList()
zip(filesList, zipFilePath)
}
}
}
网友评论