Java文件压缩ZIP


/**
 * 压缩文件
 * @param zipFiles 需要压缩的文件,或者文件夹们
 * @param outDir 输出的文件名
 */
fun zip(vararg zipFiles: File, outDir: String)
{
    if (zipFiles.isEmpty())
    {
        return
    }

    var basePath = ""
    val files = LinkedList<File>()
    for (file in zipFiles)
    {
        // 获取父级目录,有时候获取到的父级目录最后没有斜杠,需要手动添加一个斜杠
        val path = if (file.parent.endsWith(File.separatorChar))
        {
            file.parent
        } else
        {
            file.parent + File.separatorChar
        }

        if (basePath.isEmpty())
        {
            basePath = path
        } else
        {
            /**
             * 这里是比较两次目录的相同点,并且取出相同点作为目录的根节点
             */
            val pathSplit = path.split(File.separatorChar)
            val baseSplit = basePath.split(File.separatorChar)
            for (i in 0 until Math.min(pathSplit.size, baseSplit.size))
            {
                val bathPart = pathSplit[i]
                val basePart = baseSplit[i]
                if (bathPart != basePart)
                {
                    basePath = ""
                    for (j in 0 until i)
                    {
                        basePath += "${pathSplit[j]}${File.separatorChar}"
                    }
                    break
                }
            }
        }
        // 获取目录下所有的文件,或者文件本身的路径
        getFiles(file, files)
    }


    val outFile = File(outDir)
    val zipOutputStream = ZipOutputStream(CheckedOutputStream(outFile.outputStream(), CRC32()))
    val buffer = ByteArray(1024 * 1024 * 5)

    println("basePath -> $basePath")
    for (file in files)
    {
        val name = file.absolutePath.replace(basePath, "")
        println(name)
        val zipEntry = ZipEntry(name)
        zipOutputStream.putNextEntry(zipEntry)
        if (file.isFile)
        {
            val fis = file.inputStream()
            var readLen = fis.read(buffer)
            while (readLen > 0)
            {
                zipOutputStream.write(buffer, 0, readLen)
                readLen = fis.read(buffer)
            }
            fis.close()
        }
    }
    zipOutputStream.flush()
    zipOutputStream.close()
}

/**
 * 获取目录下所有的文件,或者文件本身的路径
 */
fun getFiles(file: File, result: LinkedList<File> = LinkedList()): LinkedList<File>
{
    if (file.exists())
    {
        if (file.isDirectory)
        {
            val files = file.listFiles()
            if (files.isEmpty())
            {
                result.add(file)
            } else
            {
                for (f in files)
                {
                    if (f.isDirectory)
                    {
                        getFiles(f, result)
                    } else
                    {
                        result.add(f)
                    }
                }
            }
        } else
        {
            result.add(file)
        }
    }
    return result
}