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

112
LINES

< > BotCompany Repo | #1034358 // Zip4j_MergeZipFilesWithFilter [OK]

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

Uses 204K of libraries. Click here for Pure Java version (7308L/41K).

1  
!include once #1034352 // zip4j
2  
3  
import java.nio.charset.Charset;
4  
5  
srecord noeq Zip4j_MergeZipFilesWithFilter(File zipOut) is AutoCloseable {
6  
  delegate ProgressMonitor to net.lingala.zip4j.progress.
7  
  
8  
  ZipModel zipModel;
9  
  new ZipModel zipModelOut;
10  
  SplitOutputStream outputStream;
11  
  new HeaderWriter headerWriter;
12  
  new ProgressMonitor progressMonitor;
13  
  int bufferSize = InternalZipConstants.BUFF_SIZE;
14  
  Charset charset;
15  
  new L<FileHeader> filteredFileHeaders;
16  
  
17  
  close {
18  
    dispose outputStream;
19  
  }
20  
  
21  
  void init() throws IOException {
22  
    if (outputStream == null)
23  
      outputStream = new SplitOutputStream(zipOut);
24  
  }
25  
  
26  
  void addZipFile(File zipIn, IPred<S> fileFilter) throws IOException {
27  
    init();
28  
    
29  
    try (var randomAccessFile = new RandomAccessFile(zipIn, RandomAccessFileMode.READ.getValue())) {
30  
      zipModel = new HeaderReader().readAllHeaders(randomAccessFile, buildConfig());
31  
      zipModel.setZipFile(zipIn);
32  
    }
33  
34  
    temp inputStream = new RandomAccessFile(
35  
      zipModel.getZipFile(), RandomAccessFileMode.READ.getValue());
36  
  
37  
    long currentFileCopyPointer = 0;
38  
    long runningOffset = outputStream.getFilePointer();
39  
    
40  
    L<FileHeader> sortedFileHeaders = sortedByComparator(zipModel.getCentralDirectory().getFileHeaders(), (o1, o2) -> {
41  
      if (eq(o1.getFileName(), o2.getFileName())) ret 0;
42  
      ret cmp(o1.getOffsetLocalHeader(), o2.getOffsetLocalHeader());
43  
    });
44  
  
45  
    //int count = 0;
46  
    for iFileHeader over sortedFileHeaders: {
47  
      var fileHeader = sortedFileHeaders.get(iFileHeader);
48  
      var fileHeaderOffset = fileHeader.getOffsetLocalHeader();
49  
      var nextOffset = getOffsetOfNextEntry(sortedFileHeaders, iFileHeader, zipModel);
50  
      long fp = outputStream.getFilePointer();
51  
      long lengthOfCurrentEntry = nextOffset + runningOffset - fp;
52  
      
53  
      //if (count++ < 10)
54  
        //printVars(+fileHeaderOffset, +nextOffset, +runningOffset, +lengthOfCurrentEntry, +fp);
55  
      
56  
      if (!fileFilter.get(fileHeader.getFileName())) {
57  
        runningOffset -= lengthOfCurrentEntry;
58  
        currentFileCopyPointer += lengthOfCurrentEntry;
59  
      } else {
60  
        addOffsetToFileHeader(fileHeader, runningOffset);
61  
        filteredFileHeaders.add(fileHeader);
62  
        
63  
        // copy complete entry without any changes
64  
        currentFileCopyPointer += copyFile(inputStream, outputStream,
65  
          currentFileCopyPointer,
66  
          lengthOfCurrentEntry, progressMonitor,
67  
          buildConfig().getBufferSize());
68  
      }
69  
    }
70  
71  
    var endOfCDR = zipModel.getEndOfCentralDirectoryRecord();
72  
    endOfCDR.setTotalNumberOfEntriesInCentralDirectory(l(filteredFileHeaders));
73  
    endOfCDR.setTotalNumberOfEntriesInCentralDirectoryOnThisDisk(l(filteredFileHeaders));
74  
  }
75  
  
76  
  void finish() throws IOException {
77  
    zipModelOut.getCentralDirectory().setFileHeaders(filteredFileHeaders);
78  
    headerWriter.finalizeZipFile(zipModelOut, outputStream, buildConfig().getCharset());
79  
    close();
80  
  }
81  
  
82  
  long getOffsetOfNextEntry(L<FileHeader> sortedFileHeaders,
83  
    int indexOfFileHeader, ZipModel zipModel) throws ZipException {
84  
85  
    if (indexOfFileHeader == sortedFileHeaders.size() - 1)
86  
      ret HeaderUtil.getOffsetStartOfCentralDirectory(zipModel);
87  
    else
88  
      ret sortedFileHeaders.get(indexOfFileHeader + 1).getOffsetLocalHeader();
89  
  }
90  
  
91  
  long copyFile(RandomAccessFile randomAccessFile,
92  
    OutputStream outputStream, long start, long length,
93  
    ProgressMonitor progressMonitor, int bufferSize) throws IOException {
94  
    net.lingala.zip4j.util.FileUtils.copyFile(randomAccessFile, outputStream, start, start + length, progressMonitor, bufferSize);
95  
    ret length;
96  
  }
97  
  
98  
  Zip4jConfig buildConfig() {
99  
    return new Zip4jConfig(charset, bufferSize);
100  
  }
101  
  
102  
  void addOffsetToFileHeader(FileHeader fileHeader, long offsetToAdd) {
103  
    fileHeader.setOffsetLocalHeader(fileHeader.getOffsetLocalHeader() + offsetToAdd);
104  
105  
    if (zipModel.isZip64Format()
106  
        && fileHeader.getZip64ExtendedInfo() != null
107  
        && fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() != -1)
108  
      fileHeader.getZip64ExtendedInfo().setOffsetLocalHeader(
109  
        fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() + offsetToAdd
110  
      );
111  
  }
112  
}

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: #1034358
Snippet name: Zip4j_MergeZipFilesWithFilter [OK]
Eternal ID of this version: #1034358/5
Text MD5: 070b63d9e48a477a143f44f993dd6886
Transpilation MD5: 03aef4832624156b9b9afb990ebc8055
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 07:34:55
Source code size: 4316 bytes / 112 lines
Pitched / IR pitched: No / No
Views / Downloads: 117 / 187
Version history: 4 change(s)
Referenced in: [show references]