XZip使用笔记

一.代码位置

二.引用

  1. 将JitPack存储库添加到您的构建文件中
    将其添加到存储库末尾的root build.gradle中:

    1
    2
    3
    4
    5
    6
    allprojects {
    repositories {
    ...
    maven { url 'https://jitpack.io' }
    }
    }
  2. 添加依赖项

    1
    2
    3
    4
    dependencies {
    ...
    implementation 'com.github.itemuse:XLib:Tag'
    }
  3. 初始化 Application中init

    1
    2
    3
    4
    5
    6
    7
    import cn.xy.library.XApp;
    ...
    @Override
    public void onCreate() {
    super.onCreate();
    XApp.init(this);
    }
  4. AndroidManifest.xml中添加权限

    1
    2
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    application:

    1
    android:requestLegacyExternalStorage="true"

三.几个方法

  • 压缩文件

XZip.class
第一个传入的参数是需要压缩的文件路径
第二个传入的参数是解压后的文件路径
核心压缩代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/**
* Zip the file.
*
* @param srcFilePath The path of source file.
* @param zipFilePath The path of ZIP file.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public static boolean zipFile(final String srcFilePath,
final String zipFilePath)
throws IOException {
return zipFile(XFile.getFileByPath(srcFilePath), XFile.getFileByPath(zipFilePath), null);
}
...
private static boolean zipFile(final File srcFile,
String rootPath,
final ZipOutputStream zos,
final String comment)
throws IOException {
rootPath = rootPath + (XString.isSpace(rootPath) ? "" : File.separator) + srcFile.getName();
if (srcFile.isDirectory()) {
File[] fileList = srcFile.listFiles();
if (fileList == null || fileList.length <= 0) {
ZipEntry entry = new ZipEntry(rootPath + '/');
entry.setComment(comment);
zos.putNextEntry(entry);
zos.closeEntry();
} else {
for (File file : fileList) {
if (!zipFile(file, rootPath, zos, comment)) return false;
}
}
} else {
InputStream is = null;
try {
is = new BufferedInputStream(new FileInputStream(srcFile));
ZipEntry entry = new ZipEntry(rootPath);
entry.setComment(comment);
zos.putNextEntry(entry);
byte buffer[] = new byte[BUFFER_LEN];
int len;
while ((len = is.read(buffer, 0, BUFFER_LEN)) != -1) {
zos.write(buffer, 0, len);
}
zos.closeEntry();
} finally {
if (is != null) {
is.close();
}
}
}
return true;
}

测试

1
2
3
XZip.zipFile("/storage/emulated/0/DCIM/Alipay/a.jpg","/storage/emulated/0/DCIM/Alipay/zip/a.zip");
XZip.zipFile("/storage/emulated/0/DCIM/Alipay/b.jpg","/storage/emulated/0/DCIM/Alipay/zip/b.zip");
XZip.zipFile("/storage/emulated/0/DCIM/Alipay/c.jpg","/storage/emulated/0/DCIM/Alipay/zip/c.zip");
  • 批量压缩文件

XZip.class

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Zip the files.
*
* @param srcFiles The source of files.
* @param zipFilePath The path of ZIP file.
* @return {@code true}: success<br>{@code false}: fail
* @throws IOException if an I/O error has occurred
*/
public static boolean zipFiles(final Collection<String> srcFiles,
final String zipFilePath)
throws IOException {
return zipFiles(srcFiles, zipFilePath, null);
}

批量压缩第一个参数改为传入的文件路径集合
测试

1
2
3
4
5
6
7
8
Collection<String> srcFiles = new ArrayList<>();
srcFiles.add("/storage/emulated/0/DCIM/Alipay/a.jpg");
srcFiles.add("/storage/emulated/0/DCIM/Alipay/b.jpg");
srcFiles.add("/storage/emulated/0/DCIM/Alipay/c.jpg");
srcFiles.add("/storage/emulated/0/DCIM/Alipay/d.jpg");
srcFiles.add("/storage/emulated/0/DCIM/Alipay/e.jpg");
srcFiles.add("/storage/emulated/0/DCIM/Alipay/f.jpg");
XZip.zipFiles(srcFiles,"/storage/emulated/0/DCIM/Alipay/zip/files.zip");
  • 解压文件

XZip.class
核心解压代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
* Unzip the file.
*
* @param zipFilePath The path of ZIP file.
* @param destDirPath The path of destination directory.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public static List<File> unzipFile(final String zipFilePath,
final String destDirPath)
throws IOException {
return unzipFileByKeyword(zipFilePath, destDirPath, null);
}
...
/**
* Unzip the file by keyword.
*
* @param zipFile The ZIP file.
* @param destDir The destination directory.
* @param keyword The keyboard.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public static List<File> unzipFileByKeyword(final File zipFile,
final File destDir,
final String keyword)
throws IOException {
if (zipFile == null || destDir == null) return null;
List<File> files = new ArrayList<>();
ZipFile zip = new ZipFile(zipFile);
Enumeration<?> entries = zip.entries();
try {
if (XString.isSpace(keyword)) {
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName().replace("\\", "/");
if (entryName.contains("../")) {
Log.e("XZip", "entryName: " + entryName + " is dangerous!");
continue;
}
if (!unzipChildFile(destDir, files, zip, entry, entryName)) return files;
}
} else {
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
String entryName = entry.getName().replace("\\", "/");
if (entryName.contains("../")) {
Log.e("XZip", "entryName: " + entryName + " is dangerous!");
continue;
}
if (entryName.contains(keyword)) {
if (!unzipChildFile(destDir, files, zip, entry, entryName)) return files;
}
}
}
} finally {
zip.close();
}
return files;
}

第一个参数传入的是需要解压的文件路径
第二个参数传入的是解压后的文件存放的路径
测试

1
2
XZip.unzipFile("/storage/emulated/0/DCIM/Alipay/zip/files.zip","/storage/emulated/0/DCIM/Alipay/unzip");

  • 解压带有关键字的文件

XZip.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Unzip the file by keyword.
*
* @param zipFilePath The path of ZIP file.
* @param destDirPath The path of destination directory.
* @param keyword The keyboard.
* @return the unzipped files
* @throws IOException if unzip unsuccessfully
*/
public static List<File> unzipFileByKeyword(final String zipFilePath,
final String destDirPath,
final String keyword)
throws IOException {
return unzipFileByKeyword(XFile.getFileByPath(zipFilePath), XFile.getFileByPath(destDirPath), keyword);
}

相对比解压文件多了一个传入匹配的字符
测试解压刚刚压缩的的files.zip文件

1
2
XZip.unzipFileByKeyword("/storage/emulated/0/DCIM/Alipay/zip/files.zip",
"/storage/emulated/0/DCIM/Alipay/unzip","a");

运行后只会解压a.jpg文件

  • 获取压缩文件中的文件路径链表

XZip.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Return the files' path in ZIP file.
*
* @param zipFile The ZIP file.
* @return the files' path in ZIP file
* @throws IOException if an I/O error has occurred
*/
public static List<String> getFilesPath(final File zipFile)
throws IOException {
if (zipFile == null) return null;
List<String> paths = new ArrayList<>();
ZipFile zip = new ZipFile(zipFile);
Enumeration<?> entries = zip.entries();
while (entries.hasMoreElements()) {
String entryName = ((ZipEntry) entries.nextElement()).getName().replace("\\", "/");
if (entryName.contains("../")) {
Log.e("XZip", "entryName: " + entryName + " is dangerous!");
paths.add(entryName);
} else {
paths.add(entryName);
}
}
zip.close();
return paths;
}

传入压缩文件,最终会遍历出文件后以List的格式将文件传出
测试

1
XLog.i(XZip.getFilesPath("/storage/emulated/0/DCIM/Alipay/zip/files.zip"));

打印

1
com.xy.zip I/MainActivity.java: [ (MainActivity.java:55)#onClick ] [a.jpg, b.jpg, c.jpg, d.jpg, e.jpg, f.jpg]
  • 获取压缩文件中的注释链表

XZip.class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Return the files' comment in ZIP file.
*
* @param zipFile The ZIP file.
* @return the files' comment in ZIP file
* @throws IOException if an I/O error has occurred
*/
public static List<String> getComments(final File zipFile)
throws IOException {
if (zipFile == null) return null;
List<String> comments = new ArrayList<>();
ZipFile zip = new ZipFile(zipFile);
Enumeration<?> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = ((ZipEntry) entries.nextElement());
comments.add(entry.getComment());
}
zip.close();
return comments;
}