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

104
LINES

< > BotCompany Repo | #1034357 // Zip4j_CopySubSetOfZipFile working backup 3 (full speed)

JavaX fragment (include)

!include once #1034352 // zip4j

import java.nio.charset.Charset;

srecord noeq Zip4j_CopySubSetOfZipFile(File zipIn, File zipOut, IPred<S> fileFilter) {
  delegate ProgressMonitor to net.lingala.zip4j.progress.
  
  ZipModel zipModel;
  new HeaderWriter headerWriter;
  new ProgressMonitor progressMonitor;
  int bufferSize = InternalZipConstants.BUFF_SIZE;
  Charset charset;

  run {
    try (var randomAccessFile = new RandomAccessFile(zipIn, RandomAccessFileMode.READ.getValue())) {
      zipModel = new HeaderReader().readAllHeaders(randomAccessFile, buildConfig());
      zipModel.setZipFile(zipIn);
    }

    temp outputStream = new SplitOutputStream(zipOut);
    temp inputStream = new RandomAccessFile(zipModel.getZipFile(), RandomAccessFileMode.READ.getValue());
  
    long currentFileCopyPointer = 0, runningOffset = 0;
    L<FileHeader> sortedFileHeaders = sortedByComparator(zipModel.getCentralDirectory().getFileHeaders(), (o1, o2) -> {
      if (eq(o1.getFileName(), o2.getFileName())) ret 0;
      ret cmp(o1.getOffsetLocalHeader(), o2.getOffsetLocalHeader());
    });
  
    int count = 0;
    new L<FileHeader> filteredFileHeaders;
    for iFileHeader over sortedFileHeaders: {
      var fileHeader = sortedFileHeaders.get(iFileHeader);
      var fileHeaderOffset = fileHeader.getOffsetLocalHeader();
      var nextOffset = getOffsetOfNextEntry(sortedFileHeaders, iFileHeader, zipModel);
      long fp = outputStream.getFilePointer();
      long lengthOfCurrentEntry = nextOffset + runningOffset - fp;
      
      if (count++ < 10)
        printVars(+fileHeaderOffset, +nextOffset, +runningOffset, +lengthOfCurrentEntry, +fp);
      
      if (!fileFilter.get(fileHeader.getFileName())) {
        runningOffset -= lengthOfCurrentEntry;
        currentFileCopyPointer += lengthOfCurrentEntry;
      } else {
        addOffsetToFileHeader(fileHeader, runningOffset);
        filteredFileHeaders.add(fileHeader);
        
        // copy complete entry without any changes
        currentFileCopyPointer += copyFile(inputStream, outputStream,
          currentFileCopyPointer,
          lengthOfCurrentEntry, progressMonitor,
          buildConfig().getBufferSize());
      }
    }

    var endOfCDR = zipModel.getEndOfCentralDirectoryRecord();
    endOfCDR.setTotalNumberOfEntriesInCentralDirectory(l(filteredFileHeaders));
    endOfCDR.setTotalNumberOfEntriesInCentralDirectoryOnThisDisk(l(filteredFileHeaders));
    
    if (zipModel.isZip64Format()) {
      zipModel.getZip64EndOfCentralDirectoryRecord().setOffsetStartCentralDirectoryWRTStartDiskNumber(
        zipModel.getZip64EndOfCentralDirectoryRecord().getOffsetStartCentralDirectoryWRTStartDiskNumber() + runningOffset);

      zipModel.getZip64EndOfCentralDirectoryRecord().setTotalNumberOfEntriesInCentralDirectoryOnThisDisk(l(filteredFileHeaders));

      zipModel.getZip64EndOfCentralDirectoryLocator().setOffsetZip64EndOfCentralDirectoryRecord(
          zipModel.getZip64EndOfCentralDirectoryLocator().getOffsetZip64EndOfCentralDirectoryRecord() + runningOffset);
    }
    
    zipModel.getCentralDirectory().setFileHeaders(filteredFileHeaders);
    headerWriter.finalizeZipFile(zipModel, outputStream, buildConfig().getCharset());
  }

  long getOffsetOfNextEntry(L<FileHeader> sortedFileHeaders,
    int indexOfFileHeader, ZipModel zipModel) throws ZipException {

    if (indexOfFileHeader == sortedFileHeaders.size() - 1)
      ret HeaderUtil.getOffsetStartOfCentralDirectory(zipModel);
    else
      ret sortedFileHeaders.get(indexOfFileHeader + 1).getOffsetLocalHeader();
  }
  
  long copyFile(RandomAccessFile randomAccessFile,
    OutputStream outputStream, long start, long length,
    ProgressMonitor progressMonitor, int bufferSize) throws IOException {
    net.lingala.zip4j.util.FileUtils.copyFile(randomAccessFile, outputStream, start, start + length, progressMonitor, bufferSize);
    ret length;
  }
  
  Zip4jConfig buildConfig() {
    return new Zip4jConfig(charset, bufferSize);
  }
  
  void addOffsetToFileHeader(FileHeader fileHeader, long offsetToAdd) {
    fileHeader.setOffsetLocalHeader(fileHeader.getOffsetLocalHeader() + offsetToAdd);

    if (zipModel.isZip64Format()
        && fileHeader.getZip64ExtendedInfo() != null
        && fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() != -1)
      fileHeader.getZip64ExtendedInfo().setOffsetLocalHeader(
        fileHeader.getZip64ExtendedInfo().getOffsetLocalHeader() + offsetToAdd
      );
  }
}

Author comment

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: #1034357
Snippet name: Zip4j_CopySubSetOfZipFile working backup 3 (full speed)
Eternal ID of this version: #1034357/1
Text MD5: a84eb02a0e1a4555f51603a329586652
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:26:00
Source code size: 4573 bytes / 104 lines
Pitched / IR pitched: No / No
Views / Downloads: 67 / 85
Referenced in: [show references]