Uses 204K of libraries. Click here for Pure Java version (5460L/31K).
1 | !include once #1034352 // zip4j |
2 | |
3 | import java.nio.charset.Charset; |
4 | |
5 | srecord noeq Zip4j_CopySubSetOfZipFile_workingBackup2(File zipIn, File zipOut, IPred<S> fileFilter) { |
6 | delegate ProgressMonitor to net.lingala.zip4j.progress. |
7 | |
8 | ZipModel zipModel; |
9 | new HeaderWriter headerWriter; |
10 | new ProgressMonitor progressMonitor; |
11 | int bufferSize = InternalZipConstants.BUFF_SIZE; |
12 | Charset charset; |
13 | |
14 | run { |
15 | try (var randomAccessFile = new RandomAccessFile(zipIn, RandomAccessFileMode.READ.getValue())) { |
16 | zipModel = new HeaderReader().readAllHeaders(randomAccessFile, buildConfig()); |
17 | zipModel.setZipFile(zipIn); |
18 | } |
19 | |
20 | temp outputStream = new SplitOutputStream(zipOut); |
21 | temp inputStream = new RandomAccessFile(zipModel.getZipFile(), RandomAccessFileMode.READ.getValue()); |
22 | |
23 | long currentFileCopyPointer = 0; |
24 | L<FileHeader> sortedFileHeaders = sortedByComparator(zipModel.getCentralDirectory().getFileHeaders(), (o1, o2) -> { |
25 | if (eq(o1.getFileName(), o2.getFileName())) ret 0; |
26 | ret cmp(o1.getOffsetLocalHeader(), o2.getOffsetLocalHeader()); |
27 | }); |
28 | |
29 | new L<FileHeader> filteredFileHeaders; |
30 | for iFileHeader over sortedFileHeaders: { |
31 | var fileHeader = sortedFileHeaders.get(iFileHeader); |
32 | |
33 | long lengthOfCurrentEntry = getOffsetOfNextEntry(sortedFileHeaders, iFileHeader, zipModel) - outputStream.getFilePointer(); |
34 | |
35 | if (!fileFilter.get(fileHeader.getFileName())) { |
36 | updateHeaders(sortedFileHeaders, fileHeader, lengthOfCurrentEntry); |
37 | /*if (!zipModel.getCentralDirectory().getFileHeaders().remove(fileHeader)) { |
38 | throw new ZipException("Could not remove entry from list of central directory headers"); |
39 | }*/ |
40 | |
41 | //--iFileHeader; |
42 | currentFileCopyPointer += lengthOfCurrentEntry; |
43 | } else { |
44 | filteredFileHeaders.add(fileHeader); |
45 | |
46 | // copy complete entry without any changes |
47 | currentFileCopyPointer += copyFile(inputStream, outputStream, |
48 | currentFileCopyPointer, |
49 | lengthOfCurrentEntry, progressMonitor, |
50 | buildConfig().getBufferSize()); |
51 | } |
52 | } |
53 | |
54 | zipModel.getCentralDirectory().setFileHeaders(filteredFileHeaders); |
55 | headerWriter.finalizeZipFile(zipModel, outputStream, buildConfig().getCharset()); |
56 | } |
57 | |
58 | long getOffsetOfNextEntry(L<FileHeader> sortedFileHeaders, |
59 | int indexOfFileHeader, ZipModel zipModel) throws ZipException { |
60 | |
61 | if (indexOfFileHeader == sortedFileHeaders.size() - 1) |
62 | ret HeaderUtil.getOffsetStartOfCentralDirectory(zipModel); |
63 | else |
64 | ret sortedFileHeaders.get(indexOfFileHeader + 1).getOffsetLocalHeader(); |
65 | } |
66 | |
67 | long copyFile(RandomAccessFile randomAccessFile, |
68 | OutputStream outputStream, long start, long length, |
69 | ProgressMonitor progressMonitor, int bufferSize) throws IOException { |
70 | net.lingala.zip4j.util.FileUtils.copyFile(randomAccessFile, outputStream, start, start + length, progressMonitor, bufferSize); |
71 | ret length; |
72 | } |
73 | |
74 | void updateHeaders(List<FileHeader> sortedFileHeaders, FileHeader fileHeaderThatWasRemoved, |
75 | long offsetToSubtract) throws ZipException { |
76 | updateOffsetsForAllSubsequentFileHeaders(sortedFileHeaders, zipModel, fileHeaderThatWasRemoved, safeNegate(offsetToSubtract)); |
77 | |
78 | var endOfCDR = zipModel.getEndOfCentralDirectoryRecord(); |
79 | endOfCDR.setOffsetOfStartOfCentralDirectory( |
80 | endOfCDR.getOffsetOfStartOfCentralDirectory() - offsetToSubtract); |
81 | endOfCDR.setTotalNumberOfEntriesInCentralDirectory( |
82 | endOfCDR.getTotalNumberOfEntriesInCentralDirectory() - 1); |
83 | |
84 | if (endOfCDR.getTotalNumberOfEntriesInCentralDirectoryOnThisDisk() > 0) |
85 | endOfCDR.setTotalNumberOfEntriesInCentralDirectoryOnThisDisk( |
86 | endOfCDR.getTotalNumberOfEntriesInCentralDirectoryOnThisDisk() - 1); |
87 | |
88 | if (zipModel.isZip64Format()) { |
89 | zipModel.getZip64EndOfCentralDirectoryRecord().setOffsetStartCentralDirectoryWRTStartDiskNumber( |
90 | zipModel.getZip64EndOfCentralDirectoryRecord().getOffsetStartCentralDirectoryWRTStartDiskNumber() - offsetToSubtract); |
91 | |
92 | zipModel.getZip64EndOfCentralDirectoryRecord().setTotalNumberOfEntriesInCentralDirectoryOnThisDisk( |
93 | zipModel.getZip64EndOfCentralDirectoryRecord().getTotalNumberOfEntriesInCentralDirectory() - 1); |
94 | |
95 | zipModel.getZip64EndOfCentralDirectoryLocator().setOffsetZip64EndOfCentralDirectoryRecord( |
96 | zipModel.getZip64EndOfCentralDirectoryLocator().getOffsetZip64EndOfCentralDirectoryRecord() - offsetToSubtract); |
97 | } |
98 | } |
99 | |
100 | Zip4jConfig buildConfig() { |
101 | return new Zip4jConfig(charset, bufferSize); |
102 | } |
103 | |
104 | int getIndexOfFileHeader(List<FileHeader> allFileHeaders, FileHeader fileHeaderForIndex) throws ZipException { |
105 | for (int i = 0; i < allFileHeaders.size(); i++) { |
106 | FileHeader fileHeader = allFileHeaders.get(i); |
107 | if (fileHeader.equals(fileHeaderForIndex)) { |
108 | return i; |
109 | } |
110 | } |
111 | |
112 | throw new ZipException("Could not find file header in list of central directory file headers"); |
113 | } |
114 | |
115 | void updateOffsetsForAllSubsequentFileHeaders(List<FileHeader> sortedFileHeaders, ZipModel zipModel, |
116 | FileHeader fileHeaderModified, long offsetToAdd) throws ZipException { |
117 | int indexOfFileHeader = getIndexOfFileHeader(sortedFileHeaders, fileHeaderModified); |
118 | |
119 | if (indexOfFileHeader == -1) { |
120 | throw new ZipException("Could not locate modified file header in zipModel"); |
121 | } |
122 | |
123 | for (int i = indexOfFileHeader + 1; i < sortedFileHeaders.size(); i++) { |
124 | FileHeader fileHeaderToUpdate = sortedFileHeaders.get(i); |
125 | fileHeaderToUpdate.setOffsetLocalHeader(fileHeaderToUpdate.getOffsetLocalHeader() + offsetToAdd); |
126 | |
127 | if (zipModel.isZip64Format() |
128 | && fileHeaderToUpdate.getZip64ExtendedInfo() != null |
129 | && fileHeaderToUpdate.getZip64ExtendedInfo().getOffsetLocalHeader() != -1) { |
130 | |
131 | fileHeaderToUpdate.getZip64ExtendedInfo().setOffsetLocalHeader( |
132 | fileHeaderToUpdate.getZip64ExtendedInfo().getOffsetLocalHeader() + offsetToAdd |
133 | ); |
134 | } |
135 | } |
136 | } |
137 | } |
Began life as a copy of #1034351
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, ekrmjmnbrukm, mowyntqkapby, mqqgnosmbjvj
No comments. add comment
Snippet ID: | #1034355 |
Snippet name: | Zip4j_CopySubSetOfZipFile_workingBackup2 |
Eternal ID of this version: | #1034355/2 |
Text MD5: | 95f26181f8660292440e5dec5d0296ec |
Transpilation MD5: | 0998b3ba280a513d139b25c613bdb1b1 |
Author: | stefan |
Category: | javax / io |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-02-03 06:06:41 |
Source code size: | 6139 bytes / 137 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 151 / 231 |
Version history: | 1 change(s) |
Referenced in: | [show references] |