1+ import java.io.BufferedOutputStream
12import java.io.File
23import java.io.FileInputStream
34import java.io.FileOutputStream
@@ -99,12 +100,21 @@ fun createZipFile(sourceDirPath: String, outputZipFilePath: String) {
99100private fun addFilesToZip (rootDir : File , currentDir : File , zos : ZipOutputStream ) {
100101 for (file in currentDir.listFiles() ? : emptyArray()) {
101102 if (file.isDirectory) {
103+ // 强制添加目录条目
104+ val entryPath = rootDir.toPath()
105+ .relativize(file.toPath())
106+ .toString().replace(File .separator, " /" ) + " /" // 追加斜杠
107+ zos.putNextEntry(ZipEntry (entryPath))
108+ zos.closeEntry()
102109 // 如果是目录,递归处理
103110 addFilesToZip(rootDir, file, zos)
104111 } else {
112+ // 统一文件路径分隔符为Unix格式
113+ val entryPath = rootDir.toPath()
114+ .relativize(file.toPath())
115+ .toString().replace(File .separator, " /" )
105116 // 如果是文件,添加到 ZIP
106117 FileInputStream (file).use { fis ->
107- val entryPath = rootDir.toPath().relativize(file.toPath()).toString()
108118 zos.putNextEntry(ZipEntry (entryPath))
109119 fis.copyTo(zos)
110120 zos.closeEntry()
@@ -113,38 +123,47 @@ private fun addFilesToZip(rootDir: File, currentDir: File, zos: ZipOutputStream)
113123 }
114124}
115125
116- fun unzipFile (zipFilePath : String , outputDirPath : String ) {
117- val zipFile = File (zipFilePath)
118- if (! zipFile.exists() || ! zipFile.isFile) {
119- println (" ZIP file does not exist or is not a file: $zipFilePath " )
120- return
126+ // see: https://github.com/DaemonicLabs/Voodoo/blob/8e4a0643edf10d39335ea084d00d036606901fd4/util/src/main/kotlin/voodoo/util/UnzipUtility.kt#L34
127+ // 添加跨平台处理解压处理
128+ fun unzip (zipFile : File , destDir : File ) {
129+ require(zipFile.exists()) { " $zipFile does not exist" }
130+ require(zipFile.isFile) { " $zipFile not not a file" }
131+ val destDir = destDir.absoluteFile
132+ if (! destDir.exists()) {
133+ destDir.mkdir()
121134 }
122135
123- val outputDir = File (outputDirPath)
124- if (! outputDir.exists()) {
125- outputDir.mkdirs() // 如果目标目录不存在,则创建
136+ val zipIn = ZipInputStream (FileInputStream (zipFile))
137+ var entry: ZipEntry ? = zipIn.nextEntry
138+ // iterates over entries in the zip file
139+ while (entry != null ) {
140+ // 统一转换为平台路径分隔符
141+ // val entryName = entry.name.replace("/", File.separator)
142+ val entryName = entry.name.replace(" /" , File .separator)
143+ val filePath = destDir.resolve(entryName).path
144+ if (! entry.isDirectory) {
145+ // if the entry is a file, extracts it
146+ File (filePath).parentFile.mkdirs()
147+ extractFile(zipIn, filePath)
148+ } else {
149+ // if the entry is a directory, make the directory
150+ val dir = File (filePath)
151+ dir.mkdir()
152+ }
153+ zipIn.closeEntry()
154+ entry = zipIn.nextEntry
126155 }
156+ zipIn.close()
157+ }
127158
128- // 打开 ZIP 文件并逐条解压
129- ZipInputStream (FileInputStream (zipFile)).use { zis ->
130- var entry: ZipEntry ?
131- while (zis.nextEntry.also { entry = it } != null ) {
132- val entryName = entry!! .name
133- val outputFile = File (outputDir, entryName)
134-
135- if (entry!! .isDirectory) {
136- // 如果是目录,创建目录
137- outputFile.mkdirs()
138- } else {
139- // 如果是文件,创建父目录并写入文件内容
140- outputFile.parentFile.mkdirs()
141- FileOutputStream (outputFile).use { fos ->
142- zis.copyTo(fos)
143- }
144- }
145-
146- // 关闭当前条目
147- zis.closeEntry()
148- }
159+ private fun extractFile (zipIn : ZipInputStream , filePath : String ) {
160+ val bos = BufferedOutputStream (FileOutputStream (filePath))
161+ val bytesIn = ByteArray (4096 )
162+ var read: Int
163+ while (true ) {
164+ read = zipIn.read(bytesIn)
165+ if (read < 0 ) break
166+ bos.write(bytesIn, 0 , read)
149167 }
168+ bos.close()
150169}
0 commit comments