Class ZipSplitOutputStream

All Implemented Interfaces:
Closeable, Flushable, AutoCloseable

final class ZipSplitOutputStream extends RandomAccessOutputStream
Used internally by ZipArchiveOutputStream when creating a split archive.
Since:
1.20
  • Field Details

    • ZIP_SEGMENT_MIN_SIZE

      private static final long ZIP_SEGMENT_MIN_SIZE
      8.5.1 Capacities for split archives are as follows:

      Maximum number of segments = 4,294,967,295 - 1 Maximum .ZIP segment size = 4,294,967,295 bytes (refer to section 8.5.6) Minimum segment size = 64K

      Maximum PKSFX segment size = 2,147,483,647 bytes

      See Also:
    • ZIP_SEGMENT_MAX_SIZE

      private static final long ZIP_SEGMENT_MAX_SIZE
      See Also:
    • currentChannel

      private FileChannel currentChannel
    • outputStream

      private FileRandomAccessOutputStream outputStream
    • zipFile

      private Path zipFile
    • splitSize

      private final long splitSize
    • totalPosition

      private long totalPosition
    • currentSplitSegmentIndex

      private int currentSplitSegmentIndex
    • currentSplitSegmentBytesWritten

      private long currentSplitSegmentBytesWritten
    • finished

      private boolean finished
    • singleByte

      private final byte[] singleByte
    • diskToPosition

      private final List<Long> diskToPosition
    • positionToFiles

      private final TreeMap<Long,Path> positionToFiles
  • Constructor Details

    • ZipSplitOutputStream

      ZipSplitOutputStream(File zipFile, long splitSize) throws IllegalArgumentException, IOException
      Creates a split ZIP. If the ZIP file is smaller than the split size, then there will only be one split ZIP, and its suffix is .zip, otherwise the split segments should be like .z01, .z02, ... .z(N-1), .zip
      Parameters:
      zipFile - the ZIP file to write to
      splitSize - the split size
      Throws:
      IllegalArgumentException - if arguments are illegal: Zip split segment size should between 64K and 4,294,967,295.
      IOException - if an I/O error occurs
    • ZipSplitOutputStream

      ZipSplitOutputStream(Path zipFile, long splitSize) throws IllegalArgumentException, IOException
      Creates a split ZIP. If the ZIP file is smaller than the split size, then there will only be one split ZIP, and its suffix is .zip, otherwise the split segments should be like .z01, .z02, ... .z(N-1), .zip
      Parameters:
      zipFile - the path to ZIP file to write to
      splitSize - the split size
      Throws:
      IllegalArgumentException - if arguments are illegal: Zip split segment size should between 64K and 4,294,967,295.
      IOException - if an I/O error occurs
      Since:
      1.22
  • Method Details

    • calculateDiskPosition

      public long calculateDiskPosition(long disk, long localOffset) throws IOException
      Throws:
      IOException
    • close

      public void close() throws IOException
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Overrides:
      close in class OutputStream
      Throws:
      IOException
    • createNewSplitSegmentFile

      private Path createNewSplitSegmentFile(Integer zipSplitSegmentSuffixIndex) throws IOException
      Creates the new ZIP split segment, the last ZIP segment should be .zip, and the ZIP split segments' suffix should be like .z01, .z02, .z03, ... .z99, .z100, ..., .z(N-1), .zip

      8.3.3 Split ZIP files are typically written to the same location and are subject to name collisions if the spanned name format is used since each segment will reside on the same drive. To avoid name collisions, split archives are named as follows.

      Segment 1 = filename.z01 Segment n-1 = filename.z(n-1) Segment n = filename.zip

      NOTE: The ZIP split segment begin from 1,2,3,... , and we're creating a new segment, so the new segment suffix should be (currentSplitSegmentIndex + 2)

      Parameters:
      zipSplitSegmentSuffixIndex -
      Returns:
      Throws:
      IOException
    • finish

      private void finish() throws IOException
      The last ZIP split segment's suffix should be .zip
      Throws:
      IOException
    • getCurrentSplitSegmentBytesWritten

      public long getCurrentSplitSegmentBytesWritten()
    • getCurrentSplitSegmentIndex

      public int getCurrentSplitSegmentIndex()
    • getSplitSegmentFileName

      private Path getSplitSegmentFileName(Integer zipSplitSegmentSuffixIndex)
    • openNewSplitSegment

      private void openNewSplitSegment() throws IOException
      Creates a new ZIP split segment and prepare to write to the new segment
      Throws:
      IOException
    • position

      public long position()
      Description copied from class: RandomAccessOutputStream
      Provides current position in output.
      Specified by:
      position in class RandomAccessOutputStream
      Returns:
      current position.
    • prepareToWriteUnsplittableContent

      public void prepareToWriteUnsplittableContent(long unsplittableContentSize) throws IllegalArgumentException, IOException
      Some data can not be written to different split segments, for example:

      4.4.1.5 The end of central directory record and the Zip64 end of central directory locator record MUST reside on the same disk when splitting or spanning an archive.

      Parameters:
      unsplittableContentSize -
      Throws:
      IllegalArgumentException
      IOException
    • write

      public void write(byte[] b) throws IOException
      Overrides:
      write in class OutputStream
      Throws:
      IOException
    • write

      public void write(byte[] b, int off, int len) throws IOException
      Writes the data to ZIP split segments, if the remaining space of current split segment is not enough, then a new split segment should be created
      Overrides:
      write in class OutputStream
      Parameters:
      b - data to write
      off - offset of the start of data in param b
      len - the length of data to write
      Throws:
      IOException
    • write

      public void write(int i) throws IOException
      Overrides:
      write in class RandomAccessOutputStream
      Throws:
      IOException
    • writeFully

      public void writeFully(byte[] b, int off, int len, long atPosition) throws IOException
      Description copied from class: RandomAccessOutputStream
      Writes given data to specific position.
      Specified by:
      writeFully in class RandomAccessOutputStream
      Parameters:
      b - data to write
      off - offset of the start of data in param b
      len - the length of data to write
      atPosition - position in the stream
      Throws:
      IOException - if an I/O error occurs.
    • writeToSegment

      private void writeToSegment(Path segment, long position, byte[] b, int off, int len) throws IOException
      Throws:
      IOException
    • writeZipSplitSignature

      private void writeZipSplitSignature() throws IOException
      Writes the ZIP split signature (0x08074B50) to the head of the first ZIP split segment
      Throws:
      IOException