Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

137
LINES

< > BotCompany Repo | #1034355 // Zip4j_CopySubSetOfZipFile_workingBackup2

JavaX fragment (include) [tags: use-pretranspiled]

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  
}

Author comment

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: 95 / 154
Version history: 1 change(s)
Referenced in: [show references]