在android上压缩一个装满文件的文件夹
我需要压缩一个“项目”文件夹,允许用户通过电子邮件共享项目。我找到了一个将多个文件压缩到一个zip的类,但我需要将文件夹结构保留在zip中。有没有办法在android上实现这一点?提前感谢。如果您使用java.util.zip对象,那么您可以编写一个不修改目录结构的脚本。这段代码应该可以做到这一点 注意:您必须通过向manifest.xml文件添加write_EXTERNAL_STORAGE权限来向应用程序添加文件写入权限在android上压缩一个装满文件的文件夹,android,zip,directory,compression,Android,Zip,Directory,Compression,我需要压缩一个“项目”文件夹,允许用户通过电子邮件共享项目。我找到了一个将多个文件压缩到一个zip的类,但我需要将文件夹结构保留在zip中。有没有办法在android上实现这一点?提前感谢。如果您使用java.util.zip对象,那么您可以编写一个不修改目录结构的脚本。这段代码应该可以做到这一点 注意:您必须通过向manifest.xml文件添加write_EXTERNAL_STORAGE权限来向应用程序添加文件写入权限 /* * * Zips a file at a location
/*
*
* Zips a file at a location and places the resulting zip file at the toLocation
* Example: zipFileAtPath("downloads/myfolder", "downloads/myFolder.zip");
*/
public boolean zipFileAtPath(String sourcePath, String toLocation) {
final int BUFFER = 2048;
File sourceFile = new File(sourcePath);
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(toLocation);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
if (sourceFile.isDirectory()) {
zipSubFolder(out, sourceFile, sourceFile.getParent().length());
} else {
byte data[] = new byte[BUFFER];
FileInputStream fi = new FileInputStream(sourcePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(getLastPathComponent(sourcePath));
entry.setTime(sourceFile.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
}
out.close();
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/*
*
* Zips a subfolder
*
*/
private void zipSubFolder(ZipOutputStream out, File folder,
int basePathLength) throws IOException {
final int BUFFER = 2048;
File[] fileList = folder.listFiles();
BufferedInputStream origin = null;
for (File file : fileList) {
if (file.isDirectory()) {
zipSubFolder(out, file, basePathLength);
} else {
byte data[] = new byte[BUFFER];
String unmodifiedFilePath = file.getPath();
String relativePath = unmodifiedFilePath
.substring(basePathLength);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(file.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
}
}
/*
* gets the last path component
*
* Example: getLastPathComponent("downloads/example/fileToZip");
* Result: "fileToZip"
*/
public String getLastPathComponent(String filePath) {
String[] segments = filePath.split("/");
if (segments.length == 0)
return "";
String lastPathComponent = segments[segments.length - 1];
return lastPathComponent;
}
我就是这样做的:
private static void zipFolder(String inputFolderPath, String outZipPath) {
try {
FileOutputStream fos = new FileOutputStream(outZipPath);
ZipOutputStream zos = new ZipOutputStream(fos);
File srcFile = new File(inputFolderPath);
File[] files = srcFile.listFiles();
Log.d("", "Zip directory: " + srcFile.getName());
for (int i = 0; i < files.length; i++) {
Log.d("", "Adding file: " + files[i].getName());
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream(files[i]);
zos.putNextEntry(new ZipEntry(files[i].getName()));
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
zos.closeEntry();
fis.close();
}
zos.close();
} catch (IOException ioe) {
Log.e("", ioe.getMessage());
}
}
private静态void zipFolder(字符串inputFolderPath,字符串outZipPath){
试一试{
FileOutputStream fos=新的FileOutputStream(outZipPath);
ZipoutStream zos=新ZipoutStream(fos);
File srcFile=新文件(inputFolderPath);
File[]files=srcFile.listFiles();
Log.d(“,”Zip目录:“+srcFile.getName());
对于(int i=0;i0){
写入(缓冲区,0,长度);
}
zos.closeEntry();
fis.close();
}
zos.close();
}捕获(ioe异常ioe){
Log.e(“,ioe.getMessage());
}
}
公共静态布尔zip(文件sourceFile,文件zipFile){
List fileList=getSubFiles(sourceFile,true);
ZipOutputStream ZipOutputStream=null;
试一试{
zipOutputStream=newzipoutpstream(newfileoutputstream(zipFile));
int bufferSize=1024;
字节[]buf=新字节[bufferSize];
齐彭特里;
对于(int i=0;i
使用此文件中的zip4j库。将jar文件导入您的“app/libs/”
文件夹。并使用以下代码压缩目录/文件
try {
File input = new File("path/to/your/input/fileOrFolder");
String destinationPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "zippedItem.zip";
ZipParameters parameters = new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_STORE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
File output = new File(destinationPath);
ZipFile zipFile = new ZipFile(output);
// .addFolder or .addFile depending on your input
if (sourceFile.isDirectory())
zipFile.addFolder(input, parameters);
else
zipFile.addFile(input, parameters);
// Your input file/directory has been zipped at this point and you
// can access it as a normal file using the following line of code
File zippedFile = zipFile.getFile();
} catch (ZipException e) {
Log.e(TAG, Log.getStackTraceString(e));
}
我已经修改了HailZeon的代码,以便在windows下正常工作。Zip条目必须在启动新条目之前关闭,并且在条目名称处的起始“/”如“/file.txt”也会产生问题
/**
* Zips a Folder to "[Folder].zip"
* @param toZipFolder Folder to be zipped
* @return the resulting ZipFile
*/
public static File zipFolder(File toZipFolder) {
File ZipFile = new File(toZipFolder.getParent(), format("%s.zip", toZipFolder.getName()));
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(ZipFile));
zipSubFolder(out, toZipFolder, toZipFolder.getPath().length());
out.close();
return ZipFile;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* Main zip Function
* @param out Target ZipStream
* @param folder Folder to be zipped
* @param basePathLength Length of original Folder Path (for recursion)
*/
private static void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException {
final int BUFFER = 2048;
File[] fileList = folder.listFiles();
BufferedInputStream origin = null;
for (File file : fileList) {
if (file.isDirectory()) {
zipSubFolder(out, file, basePathLength);
} else {
byte data[] = new byte[BUFFER];
String unmodifiedFilePath = file.getPath();
String relativePath = unmodifiedFilePath.substring(basePathLength + 1);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(file.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
out.closeEntry();
}
}
}
只是将@HailZeon的答案转换为Kotlin:
import java.io.BufferedInputStream
导入java.io.xml文件
导入java.io.FileInputStream
导入java.io.FileOutputStream
导入java.io.IOException
导入java.util.zip.ZipEntry
导入java.util.zip.ZipoutStream
导入java.util.zip.ZipException
private const val BUFFER=2048
/**
*将文件压缩为zip文件
*@作者阿诺·莫拉
*@自20210318年起
*@param file源文件
*@param target指向目标文件
*
*如果条目名称为空,@将引发NullPointerException
*@如果条目名称长于0xFFFF字节,则引发IllegalArgumentException
*@如果存在安全管理器及其SecurityManager.checkRead(字符串),则引发SecurityException
*方法拒绝对该文件的读取访问
*如果发生ZIP格式错误,@将引发ZipException
*@在发生I/O错误时引发IOException
*/
@投掷(
NullPointerException::类,
IllegalArgumentException::类,
SecurityException::类,
ZipException::类,
IOException::类
)
趣味zipFile(文件:文件,目标:文件){
val来源:BufferedInputStream
val dest:FileOutputStream
var zipOutput:zipOutput流?=null
试一试{
dest=target.outputStream()
zipOutput=zipOutput流(目标缓冲区(缓冲区))
if(file.isDirectory)
zipSubFolder(zipOutput,file,file.parent!!.length)
否则{
val数据=字节数组(缓冲区)
val fi=file.inputStream()
原点=缓冲的fi(缓冲区)
val entry=ZipEntry(getLastPathComponent(file.path))
entry.time=file.lastModified()
zipOutput.putNextEntry(条目)
var count=origin.read(数据,0,缓冲区)
而(计数!=-1){
写入(数据,0,计数)
count=origin.read(数据,0,缓冲区)
}
}
}最后{
zipOutput?.close()
}
}
private fun Zipusubfolder(zipOutput:zipOutput流,文件夹:File,basePathLength:Int){
val files=folder.listFiles()?:返回
变量来源:BufferedInputStream?=null
试一试{
用于(文件中的文件){
if(file.isDirectory)
ZipusubFolder(zipOutput、文件夹、basePathLength)
否则{
val数据=字节数组(缓冲区)
val unmodifiedFilePath=file.path
val relativePath=未修改的FilePath.substring(basePathLength)
/**
* Zips a Folder to "[Folder].zip"
* @param toZipFolder Folder to be zipped
* @return the resulting ZipFile
*/
public static File zipFolder(File toZipFolder) {
File ZipFile = new File(toZipFolder.getParent(), format("%s.zip", toZipFolder.getName()));
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(ZipFile));
zipSubFolder(out, toZipFolder, toZipFolder.getPath().length());
out.close();
return ZipFile;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
/**
* Main zip Function
* @param out Target ZipStream
* @param folder Folder to be zipped
* @param basePathLength Length of original Folder Path (for recursion)
*/
private static void zipSubFolder(ZipOutputStream out, File folder, int basePathLength) throws IOException {
final int BUFFER = 2048;
File[] fileList = folder.listFiles();
BufferedInputStream origin = null;
for (File file : fileList) {
if (file.isDirectory()) {
zipSubFolder(out, file, basePathLength);
} else {
byte data[] = new byte[BUFFER];
String unmodifiedFilePath = file.getPath();
String relativePath = unmodifiedFilePath.substring(basePathLength + 1);
FileInputStream fi = new FileInputStream(unmodifiedFilePath);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(relativePath);
entry.setTime(file.lastModified()); // to keep modification time after unzipping
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
out.closeEntry();
}
}
}