Uses 204K of libraries. Click here for Pure Java version (5098L/26K).
1 | !include early #1034869 // Include for exporting Java code |
2 | |
3 | !include once #1034352 // zip4j |
4 | |
5 | import java.nio.charset.Charset; |
6 | |
7 | srecord noeq Zip4j_CopySubSetOfZipFile(File zipIn, File zipOut, IPred<S> fileFilter) { |
8 | delegate ProgressMonitor to net.lingala.zip4j.progress. |
9 | |
10 | ZipModel zipModel; |
11 | new HeaderWriter headerWriter; |
12 | new ProgressMonitor progressMonitor; |
13 | int bufferSize = InternalZipConstants.BUFF_SIZE; |
14 | Charset charset; |
15 | |
16 | run { |
17 | try (var randomAccessFile = new RandomAccessFile(zipIn, RandomAccessFileMode.READ.getValue())) { |
18 | zipModel = new HeaderReader().readAllHeaders(randomAccessFile, buildConfig()); |
19 | zipModel.setZipFile(zipIn); |
20 | } |
21 | |
22 | temp outputStream = new SplitOutputStream(zipOut); |
23 | temp inputStream = new RandomAccessFile(zipModel.getZipFile(), RandomAccessFileMode.READ.getValue()); |
24 | |
25 | long currentFileCopyPointer = 0, runningOffset = 0; |
26 | L<FileHeader> sortedFileHeaders = sortedByComparator(zipModel.getCentralDirectory().getFileHeaders(), (o1, o2) -> { |
27 | if (eq(o1.getFileName(), o2.getFileName())) ret 0; |
28 | ret cmp(o1.getOffsetLocalHeader(), o2.getOffsetLocalHeader()); |
29 | }); |
30 | |
31 | int count = 0; |
32 | new L<FileHeader> filteredFileHeaders; |
33 | for iFileHeader over sortedFileHeaders: { |
34 | var fileHeader = sortedFileHeaders.get(iFileHeader); |
35 | var fileHeaderOffset = fileHeader.getOffsetLocalHeader(); |
36 | var nextOffset = getOffsetOfNextEntry(sortedFileHeaders, iFileHeader, zipModel); |
37 | long fp = outputStream.getFilePointer(); |
38 | long lengthOfCurrentEntry = nextOffset + runningOffset - fp; |
39 | |
40 | if (count++ < 10) |
41 | printVars(+fileHeaderOffset, +nextOffset, +runningOffset, +lengthOfCurrentEntry, +fp); |
42 | |
43 | if (!fileFilter.get(fileHeader.getFileName())) { |
44 | runningOffset -= lengthOfCurrentEntry; |
45 | currentFileCopyPointer += lengthOfCurrentEntry; |
46 | } else { |
47 | addOffsetToFileHeader(fileHeader, runningOffset); |
48 | filteredFileHeaders.add(fileHeader); |
49 | |
50 | // copy complete entry without any changes |
51 | currentFileCopyPointer += copyFile(inputStream, outputStream, |
52 | currentFileCopyPointer, |
53 | lengthOfCurrentEntry, progressMonitor, |
54 | buildConfig().getBufferSize()); |
55 | } |
56 | } |
57 | |
58 | var endOfCDR = zipModel.getEndOfCentralDirectoryRecord(); |
59 | endOfCDR.setTotalNumberOfEntriesInCentralDirectory(l(filteredFileHeaders)); |
60 | endOfCDR.setTotalNumberOfEntriesInCentralDirectoryOnThisDisk(l(filteredFileHeaders)); |
61 | |
62 | if (zipModel.isZip64Format()) { |
63 | zipModel.getZip64EndOfCentralDirectoryRecord().setOffsetStartCentralDirectoryWRTStartDiskNumber( |
64 | zipModel.getZip64EndOfCentralDirectoryRecord().getOffsetStartCentralDirectoryWRTStartDiskNumber() + runningOffset); |
65 | |
66 | zipModel.getZip64EndOfCentralDirectoryRecord().setTotalNumberOfEntriesInCentralDirectoryOnThisDisk(l(filteredFileHeaders)); |
67 | |
68 | zipModel.getZip64EndOfCentralDirectoryLocator().setOffsetZip64EndOfCentralDirectoryRecord( |
69 | zipModel.getZip64EndOfCentralDirectoryLocator().getOffsetZip64EndOfCentralDirectoryRecord() + runningOffset); |
70 | } |
71 | |
72 | zipModel.getCentralDirectory().setFileHeaders(filteredFileHeaders); |
73 | headerWriter.finalizeZipFile(zipModel, outputStream, buildConfig().getCharset()); |
74 | } |
75 | |
76 | long getOffsetOfNextEntry(L<FileHeader> sortedFileHeaders, |
77 | int indexOfFileHeader, ZipModel zipModel) throws ZipException { |
78 | |
79 | if (indexOfFileHeader == sortedFileHeaders.size() - 1) |
80 | ret HeaderUtil.getOffsetStartOfCentralDirectory(zipModel); |
81 | else |
82 | ret sortedFileHeaders.get(indexOfFileHeader + 1).getOffsetLocalHeader(); |
83 | } |
84 | |
85 | long copyFile(RandomAccessFile randomAccessFile, |
86 | OutputStream outputStream, long start, long length, |
87 | ProgressMonitor progressMonitor, int bufferSize) throws IOException { |
88 | net.lingala.zip4j.util.FileUtils.copyFile(randomAccessFile, outputStream, start, start + length, progressMonitor, bufferSize); |
89 | ret length; |
90 | } |
91 | |
92 | Zip4jConfig buildConfig() { |
93 | return new Zip4jConfig(charset, bufferSize); |
94 | } |
95 | |
96 | void addOffsetToFileHeader(FileHeader fileHeader, long offsetToAdd) { |
97 | fileHeader.setOffsetLocalHeader(fileHeader.getOffsetLocalHeader() + offsetToAdd); |
98 | |
99 | if (zipModel.isZip64Format() |
100 | && fileHeader.getZip64ExtendedInfo() != null |
101 | && fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() != -1) |
102 | fileHeader.getZip64ExtendedInfo().setOffsetLocalHeader( |
103 | fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() + offsetToAdd |
104 | ); |
105 | } |
106 | } |
Began life as a copy of #1034351
download show line numbers debug dex old transpilations
Travelled to 3 computer(s): bhatertpkbcr, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1034356 |
Snippet name: | Zip4j_CopySubSetOfZipFile for export |
Eternal ID of this version: | #1034356/3 |
Text MD5: | c7a213108ba4ee32af68d340b399c4ce |
Transpilation MD5: | 691056d915e3ef73fc2c7e329669c3e0 |
Author: | stefan |
Category: | javax / io |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-03-12 22:02:10 |
Source code size: | 4635 bytes / 106 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 138 / 236 |
Version history: | 2 change(s) |
Referenced in: | [show references] |