Android 如何压缩和解压文件?

Android 如何压缩和解压文件?,android,file,zip,unzip,Android,File,Zip,Unzip,如何压缩和解压DDMS中已经存在的文件:data/data/mypackage/files/我需要一个简单的例子。我已经搜索了与zip和unzip相关的内容。但是,没有一个例子适合我。谁能举个例子吗。提前感谢。看看java.util.zip.*类的zip功能。我已经完成了一些基本的zip/解压代码,我已经粘贴在下面。希望能有帮助 public static void zip(String[] files, String zipFile) throws IOException { Buff

如何压缩和解压DDMS中已经存在的文件:
data/data/mypackage/files/
我需要一个简单的例子。我已经搜索了与zip和unzip相关的内容。但是,没有一个例子适合我。谁能举个例子吗。提前感谢。

看看java.util.zip.*类的zip功能。我已经完成了一些基本的zip/解压代码,我已经粘贴在下面。希望能有帮助

public static void zip(String[] files, String zipFile) throws IOException {
    BufferedInputStream origin = null;
    ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
    try { 
        byte data[] = new byte[BUFFER_SIZE];

        for (int i = 0; i < files.length; i++) {
            FileInputStream fi = new FileInputStream(files[i]);    
            origin = new BufferedInputStream(fi, BUFFER_SIZE);
            try {
                ZipEntry entry = new ZipEntry(files[i].substring(files[i].lastIndexOf("/") + 1));
                out.putNextEntry(entry);
                int count;
                while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) {
                    out.write(data, 0, count);
                }
            }
            finally {
                origin.close();
            }
        }
    }
    finally {
        out.close();
    }
}

public static void unzip(String zipFile, String location) throws IOException {
    try {
        File f = new File(location);
        if(!f.isDirectory()) {
            f.mkdirs();
        }
        ZipInputStream zin = new ZipInputStream(new FileInputStream(zipFile));
        try {
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {
                String path = location + ze.getName();

                if (ze.isDirectory()) {
                    File unzipFile = new File(path);
                    if(!unzipFile.isDirectory()) {
                        unzipFile.mkdirs();
                    }
                }
                else {
                    FileOutputStream fout = new FileOutputStream(path, false);
                    try {
                        for (int c = zin.read(); c != -1; c = zin.read()) {
                            fout.write(c);
                        }
                        zin.closeEntry();
                    }
                    finally {
                        fout.close();
                    }
                }
            }
        }
        finally {
            zin.close();
        }
    }
    catch (Exception e) {
        Log.e(TAG, "Unzip exception", e);
    }
}
publicstaticvoidzip(String[]文件,stringzipfile)抛出IOException{
BufferedInputStream原点=null;
ZipOutputStream out=new-zipoutpstream(new-BufferedOutputStream(new-FileOutputStream(zipFile));
试试{
字节数据[]=新字节[缓冲区大小];
对于(int i=0;i
brianestey提供的zip函数运行良好,但解压函数非常慢,因为它一次只能读取一个字节。这是他的解压功能的一个修改版本,它利用了缓冲区,速度更快

/**
 * Unzip a zip file.  Will overwrite existing files.
 * 
 * @param zipFile Full path of the zip file you'd like to unzip.
 * @param location Full path of the directory you'd like to unzip to (will be created if it doesn't exist).
 * @throws IOException
 */
public static void unzip(String zipFile, String location) throws IOException {
    int size;
    byte[] buffer = new byte[BUFFER_SIZE];

    try {
        if ( !location.endsWith(File.separator) ) {
            location += File.separator;
        }
        File f = new File(location);
        if(!f.isDirectory()) {
            f.mkdirs();
        }
        ZipInputStream zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile), BUFFER_SIZE));
        try {
            ZipEntry ze = null;
            while ((ze = zin.getNextEntry()) != null) {
                String path = location + ze.getName();
                File unzipFile = new File(path);

                if (ze.isDirectory()) {
                    if(!unzipFile.isDirectory()) {
                        unzipFile.mkdirs();
                    }
                } else {
                    // check for and create parent directories if they don't exist
                    File parentDir = unzipFile.getParentFile();
                    if ( null != parentDir ) {
                        if ( !parentDir.isDirectory() ) {
                            parentDir.mkdirs();
                        }
                    }

                    // unzip the file
                    FileOutputStream out = new FileOutputStream(unzipFile, false);
                    BufferedOutputStream fout = new BufferedOutputStream(out, BUFFER_SIZE);
                    try {
                        while ( (size = zin.read(buffer, 0, BUFFER_SIZE)) != -1 ) {
                            fout.write(buffer, 0, size);
                        }

                        zin.closeEntry();
                    }
                    finally {
                        fout.flush();
                        fout.close();
                    }
                }
            }
        }
        finally {
            zin.close();
        }
    }
    catch (Exception e) {
        Log.e(TAG, "Unzip exception", e);
    }
}
使用
文件
而不是文件路径
字符串
。 这个答案是根据我们的经验得出的

我修改了他的
zip
方法,以接受文件列表而不是文件路径,并接受输出zip文件而不是文件路径,如果其他人正在处理这些文件,这可能会对他们有所帮助

public static void zip( List<File> files, File zipFile ) throws IOException {
    final int BUFFER_SIZE = 2048;

    BufferedInputStream origin = null;
    ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));

    try {
        byte data[] = new byte[BUFFER_SIZE];

        for ( File file : files ) {
            FileInputStream fileInputStream = new FileInputStream( file );

            origin = new BufferedInputStream(fileInputStream, BUFFER_SIZE);

            String filePath = file.getAbsolutePath();

            try {
                ZipEntry entry = new ZipEntry( filePath.substring( filePath.lastIndexOf("/") + 1 ) );

                out.putNextEntry(entry);

                int count;
                while ((count = origin.read(data, 0, BUFFER_SIZE)) != -1) {
                    out.write(data, 0, count);
                }
            }
            finally {
                origin.close();
            }
        }
    }
    finally {
        out.close();
    }
}
publicstaticvoidzip(列表文件、文件zipFile)引发IOException{
最终整数缓冲区大小=2048;
BufferedInputStream原点=null;
ZipOutputStream out=new-zipoutpstream(new-BufferedOutputStream(new-FileOutputStream(zipFile));
试一试{
字节数据[]=新字节[缓冲区大小];
用于(文件:文件){
FileInputStream FileInputStream=新的FileInputStream(文件);
原点=新的BufferedInputStream(fileInputStream,缓冲区大小);
字符串filePath=file.getAbsolutePath();
试一试{
ZipEntry entry=newzipentry(filePath.substring(filePath.lastIndexOf(“/”+1));
外出、外出(进入);
整数计数;
while((count=origin.read(数据,0,缓冲区大小))!=-1){
输出。写入(数据,0,计数);
}
}
最后{
origin.close();
}
}
}
最后{
out.close();
}
}

这个答案是基于布莱恩斯泰、本、贾科莫·马蒂乌齐、约书亚·品特的

函数重写为Kotlin,并添加了用于处理Uri的函数。
导入android.content.Context
导入android.net.Uri
导入java.io*
导入java.util.zip.ZipEntry
导入java.util.zip.ZipInputStream
导入java.util.zip.ZipoutStream
私有const val MODE_WRITE=“w”
私有const val MODE_READ=“r”
趣味zip(zipFile:文件,文件:列表){
ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile)))。使用{outStream->
zip(扩展、文件)
}
}
funzip(上下文:context,zipFile:Uri,文件:List){
contentResolver.openFileDescriptor(zipFile,MODE_WRITE)。使用{descriptor->
描述符?.fileDescriptor?.let{
ZipOutputStream(BufferedOutputStream(FileOutputStream(it)))。使用{outStream->
zip(扩展、文件)
}
}
}
}
private fun zip(扩展:ZipoutStream,文件:列表){
files.forEach{file->
outStream.putnextery(ZipEntry(file.name))
BufferedInputStream(FileInputStream(file))。使用{inStream->
流内复制(流外)
}
}
}
乐趣解压(zipFile:文件,位置:文件){
ZipInputStream(BufferedInputStream(FileInputStream(zipFile))。使用{inStream->
解压(流内,位置)
}
}
乐趣解压(上下文:context,zipFile:Uri,位置:File){
contentResolver.openFileDescriptor(zipFile,MODE_READ)。使用{descriptor->
描述符?.fileDescriptor?.let{
ZipInputStream(BufferedInputStream(FileInputStream(it))。使用{inStream->
解压(流内,位置)
}
}
}
}
私人娱乐解压(inStream:ZipInputStream,位置:File){
if(location.exists()
import android.content.Context
import android.net.Uri
import java.io.*
import java.util.zip.ZipEntry
import java.util.zip.ZipInputStream
import java.util.zip.ZipOutputStream

private const val MODE_WRITE = "w"
private const val MODE_READ = "r"

fun zip(zipFile: File, files: List<File>) {
    ZipOutputStream(BufferedOutputStream(FileOutputStream(zipFile))).use { outStream ->
        zip(outStream, files)
    }
}

fun zip(context: Context, zipFile: Uri, files: List<File>) {
    context.contentResolver.openFileDescriptor(zipFile, MODE_WRITE).use { descriptor ->
        descriptor?.fileDescriptor?.let {
            ZipOutputStream(BufferedOutputStream(FileOutputStream(it))).use { outStream ->
                zip(outStream, files)
            }
        }
    }
}

private fun zip(outStream: ZipOutputStream, files: List<File>) {
    files.forEach { file ->
        outStream.putNextEntry(ZipEntry(file.name))
        BufferedInputStream(FileInputStream(file)).use { inStream ->
            inStream.copyTo(outStream)
        }
    }
}

fun unzip(zipFile: File, location: File) {
    ZipInputStream(BufferedInputStream(FileInputStream(zipFile))).use { inStream ->
        unzip(inStream, location)
    }
}

fun unzip(context: Context, zipFile: Uri, location: File) {
    context.contentResolver.openFileDescriptor(zipFile, MODE_READ).use { descriptor ->
        descriptor?.fileDescriptor?.let {
            ZipInputStream(BufferedInputStream(FileInputStream(it))).use { inStream ->
                unzip(inStream, location)
            }
        }
    }
}

private fun unzip(inStream: ZipInputStream, location: File) {
    if (location.exists() && !location.isDirectory)
        throw IllegalStateException("Location file must be directory or not exist")

    if (!location.isDirectory) location.mkdirs()

    val locationPath = location.absolutePath.let {
        if (!it.endsWith(File.separator)) "$it${File.separator}"
        else it
    }

    var zipEntry: ZipEntry?
    var unzipFile: File
    var unzipParentDir: File?

    while (inStream.nextEntry.also { zipEntry = it } != null) {
        unzipFile = File(locationPath + zipEntry!!.name)
        if (zipEntry!!.isDirectory) {
            if (!unzipFile.isDirectory) unzipFile.mkdirs()
        } else {
            unzipParentDir = unzipFile.parentFile
            if (unzipParentDir != null && !unzipParentDir.isDirectory) {
                unzipParentDir.mkdirs()
            }
            BufferedOutputStream(FileOutputStream(unzipFile)).use { outStream ->
                inStream.copyTo(outStream)
            }
        }
    }
}