Class ArchiveBuilder

java.lang.Object
io.smallrye.common.io.archive.ArchiveBuilder
All Implemented Interfaces:
Closeable, AutoCloseable

@Experimental("Incubating archive API") public final class ArchiveBuilder extends Object implements Closeable
A builder for creating ZIP/JAR archive files.

The builder writes entries sequentially to the archive. Each file entry returns an OutputStream that must be closed before another entry can be added. Closing the builder writes the central directory and end-of-central-directory records to complete the archive.

The archive is written using a BufferedFile, which allows random-access patching of CRC-32 and size fields in local file headers after entry data has been written. All file names are encoded as UTF-8 (general purpose bit 11 is always set).

Usage example


 try (ArchiveBuilder builder = ArchiveBuilder.open(path)) {
     builder.addDirectory("META-INF/");
     try (OutputStream os = builder.addEntry("META-INF/MANIFEST.MF", Set.of(ZipOption.STORED))) {
         os.write(manifestBytes);
     }
     try (OutputStream os = builder.addEntry("com/example/Main.class")) {
         os.write(classBytes);
     }
 }
 

Compression

The compression method can be set at the builder level (as a default for all entries) and/or per entry. Per-entry options override the builder default. If no compression option is specified at either level, the default is ZipOption.DEFLATED.

ZIP64 support

By default, entries are written in standard ZIP format. If any single entry may exceed 4 GB, pass ZipOption.ZIP64 to the open(Path, Collection, FileAttribute[]) factory method (as a builder-level default) or to addEntry(String, Collection, FileAttribute[]) (for individual entries) to reserve ZIP64 extended information in the local file header. The central directory and end-of-central-directory records will use ZIP64 format when necessary, regardless of this option.

Thread safety

This class is not thread-safe.
See Also:
  • Method Details

    • open

      public static ArchiveBuilder open(Path path) throws IOException
      Open a new archive builder for writing to the given path. The file is created if it does not exist. If the file already exists, its previous contents are overwritten. This is equivalent to calling open(Path, Collection, FileAttribute...) with an empty options set.
      Parameters:
      path - the path of the archive file to create (must not be null)
      Returns:
      a new archive builder (not null)
      Throws:
      IOException - if an I/O error occurs
    • open

      public static ArchiveBuilder open(Path path, FileAttribute<?>... attrs) throws IOException
      Open a new archive builder for writing to the given path. The file is created if it does not exist. If the file already exists, its previous contents are overwritten. The optional file attributes are applied to the created file on the filesystem. This is equivalent to calling open(Path, Collection, FileAttribute...) with an empty options set.
      Parameters:
      path - the path of the archive file to create (must not be null)
      attrs - optional file attributes to set on the created file
      Returns:
      a new archive builder (not null)
      Throws:
      IOException - if an I/O error occurs
    • open

      public static ArchiveBuilder open(Path path, OpenOption... options) throws IOException
      Open a new archive builder for writing to the given path, with the given options. See open(Path, Collection, FileAttribute...) for details on how options are handled.
      Parameters:
      path - the path of the archive file to create (must not be null)
      options - the open options (must not be null); may contain ZipOption values and/or StandardOpenOption values
      Returns:
      a new archive builder (not null)
      Throws:
      IOException - if an I/O error occurs
      UnsupportedOperationException - if an unsupported option is specified
    • open

      public static ArchiveBuilder open(Path path, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Open a new archive builder for writing to the given path, with the given options. The file is always opened for both reading and writing. By default, the file is created if it does not exist, and its previous contents (if any) are overwritten.

      The following StandardOpenOption values are accepted:

      • CREATE_NEW — create the file atomically; an exception is thrown if the file already exists
      • TRUNCATE_EXISTING — truncate the file to zero length when opened (this is the default behavior when CREATE_NEW is not given)
      • CREATE, READ, WRITE — accepted silently (these behaviors are always implied)
      ZipOption values may also be specified to set builder-level defaults. The optional file attributes are applied to the created file on the filesystem.
      Parameters:
      path - the path of the archive file to create (must not be null)
      options - the open options (must not be null); may contain ZipOption values and/or StandardOpenOption values
      attrs - optional file attributes to set on the created file
      Returns:
      a new archive builder (not null)
      Throws:
      IOException - if an I/O error occurs
      UnsupportedOperationException - if an unsupported option is specified
    • open

      public static ArchiveBuilder open(BufferedFile file, OpenOption... options) throws IOException
      Open a new archive builder for writing to an existing BufferedFile. The file must be open for both reading and writing. When the builder is closed, the central directory is written but the BufferedFile itself is not closed. The BufferedFile may not be used until the builder is closed, because the builder opens a nested file on it.

      ZipOption values may be specified to set builder-level defaults. CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since the file is already open.

      Parameters:
      file - the buffered file to write the archive to (must not be null)
      options - the options (must not be null); may contain ZipOption values
      Returns:
      a new archive builder (not null)
      Throws:
      IOException - if an I/O error occurs
      UnsupportedOperationException - if an unsupported option is specified
    • open

      public static ArchiveBuilder open(BufferedFile file, Collection<? extends OpenOption> options) throws IOException
      Open a new archive builder for writing to an existing BufferedFile. The file must be open for both reading and writing. When the builder is closed, the central directory is written but the BufferedFile itself is not closed.

      ZipOption values may be specified to set builder-level defaults. CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since the file is already open.

      Parameters:
      file - the buffered file to write the archive to (must not be null)
      options - the options (must not be null); may contain ZipOption values
      Returns:
      a new archive builder (not null)
      Throws:
      IOException - if an I/O error occurs
      UnsupportedOperationException - if an unsupported option is specified
    • position

      public long position() throws IOException
      Returns the current position within the archive, in bytes. The position is relative to the start of the archive data, not to the start of the underlying file. This method may only be called when no entry is currently being written.
      Returns:
      the current position within the archive, in bytes
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addDirectory

      public void addDirectory(String name, FileAttribute<?>... attrs) throws IOException
      Add a directory entry to the archive. A trailing '/' is appended to the name if not already present. Directory entries are always stored with the STORED method, zero CRC-32, and zero size.
      Parameters:
      name - the directory name (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public OutputStream addEntry(String name) throws IOException
      Add a file entry to the archive using the builder's default options and no file attributes. The returned output stream must be closed before another entry can be added or the archive can be closed.
      Parameters:
      name - the entry name (must not be null)
      Returns:
      an output stream to which the entry data should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public OutputStream addEntry(String name, OpenOption... options) throws IOException
      Add a file entry to the archive with the given options and no file attributes. Options given here override the builder-level defaults for this entry. The returned output stream must be closed before another entry can be added or the archive can be closed.
      Parameters:
      name - the entry name (must not be null)
      options - the entry options; may contain ZipOption values
      Returns:
      an output stream to which the entry data should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public OutputStream addEntry(String name, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the given options. Options given here override the builder-level defaults for this entry. The returned output stream must be closed before another entry can be added or the archive can be closed.
      Parameters:
      name - the entry name (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Returns:
      an output stream to which the entry data should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public OutputStream addEntry(String name, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the given options. Options given here override the builder-level defaults for this entry. The returned output stream must be closed before another entry can be added or the archive can be closed.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Returns:
      an output stream to which the entry data should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, InputStream content) throws IOException
      Add a file entry to the archive with the content read from the given input stream, using the builder's default options and no file attributes. All bytes are read from the input stream using InputStream.transferTo(OutputStream). The input stream is not closed by this method.
      Parameters:
      name - the entry name (must not be null)
      content - the input stream to read from (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, InputStream content, OpenOption... options) throws IOException
      Add a file entry to the archive with the content read from the given input stream and the given options. All bytes are read from the input stream using InputStream.transferTo(OutputStream). The input stream is not closed by this method.
      Parameters:
      name - the entry name (must not be null)
      content - the input stream to read from (must not be null)
      options - the entry options; may contain ZipOption values
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, InputStream content, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content read from the given input stream and the given file attributes. All bytes are read from the input stream using InputStream.transferTo(OutputStream). The input stream is not closed by this method.
      Parameters:
      name - the entry name (must not be null)
      content - the input stream to read from (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, InputStream content, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content read from the given input stream, with the given options and file attributes. All bytes are read from the input stream using InputStream.transferTo(OutputStream). The input stream is not closed by this method.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      content - the input stream to read from (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, byte[] content) throws IOException
      Add a file entry to the archive with the content from the given byte array, using the builder's default options and no file attributes.
      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, byte[] content, OpenOption... options) throws IOException
      Add a file entry to the archive with the content from the given byte array, with the given options.
      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write (must not be null)
      options - the entry options; may contain ZipOption values
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, byte[] content, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content from the given byte array, with the given file attributes.
      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, byte[] content, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content from the given byte array, with the given options and file attributes.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, byte[] content, int offset, int length) throws IOException
      Add a file entry to the archive with the content from a region of the given byte array, using the builder's default options and no file attributes.
      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write from (must not be null)
      offset - the start offset in the array
      length - the number of bytes to write
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IndexOutOfBoundsException - if offset or length is negative, or offset + length exceeds the array length
    • addEntry

      public void addEntry(String name, byte[] content, int offset, int length, OpenOption... options) throws IOException
      Add a file entry to the archive with the content from a region of the given byte array, with the given options.
      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write from (must not be null)
      offset - the start offset in the array
      length - the number of bytes to write
      options - the entry options; may contain ZipOption values
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
      IndexOutOfBoundsException - if offset or length is negative, or offset + length exceeds the array length
    • addEntry

      public void addEntry(String name, byte[] content, int offset, int length, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content from a region of the given byte array, with the given file attributes.
      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write from (must not be null)
      offset - the start offset in the array
      length - the number of bytes to write
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IndexOutOfBoundsException - if offset or length is negative, or offset + length exceeds the array length
    • addEntry

      public void addEntry(String name, byte[] content, int offset, int length, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content from a region of the given byte array, with the given options and file attributes.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      content - the byte array to write from (must not be null)
      offset - the start offset in the array
      length - the number of bytes to write
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
      IndexOutOfBoundsException - if offset or length is negative, or offset + length exceeds the array length
    • addEntry

      public Writer addEntry(String name, Charset charset) throws IOException
      Add a file entry to the archive and return a Writer for writing text content, using the builder's default options and no file attributes. The returned writer wraps an OutputStreamWriter over the entry's output stream. The writer must be closed before another entry can be added or the archive can be closed.
      Parameters:
      name - the entry name (must not be null)
      charset - the character set for encoding text (must not be null)
      Returns:
      a writer to which the entry text should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public Writer addEntry(String name, Charset charset, OpenOption... options) throws IOException
      Add a file entry to the archive and return a Writer for writing text content, with the given options. The returned writer wraps an OutputStreamWriter over the entry's output stream. The writer must be closed before another entry can be added or the archive can be closed.
      Parameters:
      name - the entry name (must not be null)
      charset - the character set for encoding text (must not be null)
      options - the entry options; may contain ZipOption values
      Returns:
      a writer to which the entry text should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public Writer addEntry(String name, Charset charset, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive and return a Writer for writing text content, with the given file attributes. The returned writer wraps an OutputStreamWriter over the entry's output stream. The writer must be closed before another entry can be added or the archive can be closed.
      Parameters:
      name - the entry name (must not be null)
      charset - the character set for encoding text (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Returns:
      a writer to which the entry text should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public Writer addEntry(String name, Charset charset, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive and return a Writer for writing text content, with the given options and file attributes. The returned writer wraps an OutputStreamWriter over the entry's output stream. The writer must be closed before another entry can be added or the archive can be closed.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      charset - the character set for encoding text (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Returns:
      a writer to which the entry text should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, CharSequence content, Charset charset) throws IOException
      Add a file entry to the archive with the text content read from the given character sequence, using the builder's default options and no file attributes. The character sequence is encoded using the given character set.
      Parameters:
      name - the entry name (must not be null)
      content - the character sequence to write (must not be null)
      charset - the character set for encoding text (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, CharSequence content, Charset charset, OpenOption... options) throws IOException
      Add a file entry to the archive with the text content read from the given character sequence, with the given options. The character sequence is encoded using the given character set.
      Parameters:
      name - the entry name (must not be null)
      content - the character sequence to write (must not be null)
      charset - the character set for encoding text (must not be null)
      options - the entry options; may contain ZipOption values
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, CharSequence content, Charset charset, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the text content read from the given character sequence, with the given file attributes. The character sequence is encoded using the given character set.
      Parameters:
      name - the entry name (must not be null)
      content - the character sequence to write (must not be null)
      charset - the character set for encoding text (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, CharSequence content, Charset charset, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the text content read from the given character sequence, with the given options and file attributes. The character sequence is encoded using the given character set.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      content - the character sequence to write (must not be null)
      charset - the character set for encoding text (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, Reader content, Charset charset) throws IOException
      Add a file entry to the archive with the text content read from the given reader, using the builder's default options and no file attributes. All characters are read from the reader and encoded using the given character set. The reader is not closed by this method.
      Parameters:
      name - the entry name (must not be null)
      content - the reader to read from (must not be null)
      charset - the character set for encoding text (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, Reader content, Charset charset, OpenOption... options) throws IOException
      Add a file entry to the archive with the text content read from the given reader, with the given options. All characters are read from the reader and encoded using the given character set. The reader is not closed by this method.
      Parameters:
      name - the entry name (must not be null)
      content - the reader to read from (must not be null)
      charset - the character set for encoding text (must not be null)
      options - the entry options; may contain ZipOption values
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, Reader content, Charset charset, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the text content read from the given reader, with the given file attributes. All characters are read from the reader and encoded using the given character set. The reader is not closed by this method.
      Parameters:
      name - the entry name (must not be null)
      content - the reader to read from (must not be null)
      charset - the character set for encoding text (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, Reader content, Charset charset, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the text content read from the given reader, with the given options and file attributes. All characters are read from the reader and encoded using the given character set. The reader is not closed by this method.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      content - the reader to read from (must not be null)
      charset - the character set for encoding text (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, Path content) throws IOException
      Add a file entry to the archive with the content copied from the given path, using the builder's default options and no file attributes. The file content is copied using Files.copy(Path, OutputStream).
      Parameters:
      name - the entry name (must not be null)
      content - the path of the file to copy from (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, Path content, OpenOption... options) throws IOException
      Add a file entry to the archive with the content copied from the given path, with the given options. The file content is copied using Files.copy(Path, OutputStream).
      Parameters:
      name - the entry name (must not be null)
      content - the path of the file to copy from (must not be null)
      options - the entry options; may contain ZipOption values
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addEntry

      public void addEntry(String name, Path content, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content copied from the given path, with the given file attributes. The file content is copied using Files.copy(Path, OutputStream).
      Parameters:
      name - the entry name (must not be null)
      content - the path of the file to copy from (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
    • addEntry

      public void addEntry(String name, Path content, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive with the content copied from the given path, with the given options and file attributes. The file content is copied using Files.copy(Path, OutputStream).

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      content - the path of the file to copy from (must not be null)
      options - the entry options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry output stream is still open, or this builder is closed
      IllegalArgumentException - if conflicting compression options are specified
      UnsupportedOperationException - if an unsupported option is specified
    • addBufferedEntry

      public BufferedFile addBufferedEntry(String name) throws IOException
      Add a file entry to the archive that is backed by a nested BufferedFile rather than an output stream, using the builder's default options and no file attributes. The returned file allows random-access writing of the entry data. The entry is always stored with the STORED method because random-access writing is incompatible with compression. The returned file must be closed before another entry can be added or the archive can be closed. When closed, the CRC-32 is computed from the written data and the local file header is patched with the final CRC and size values.
      Parameters:
      name - the entry name (must not be null)
      Returns:
      the nested file for writing entry data (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
    • addBufferedEntry

      public BufferedFile addBufferedEntry(String name, OpenOption... options) throws IOException
      Add a file entry to the archive that is backed by a nested BufferedFile rather than an output stream. The returned file allows random-access writing of the entry data. The entry is always stored with the STORED method because random-access writing is incompatible with compression. The returned file must be closed before another entry can be added or the archive can be closed. When closed, the CRC-32 is computed from the written data and the local file header is patched with the final CRC and size values.
      Parameters:
      name - the entry name (must not be null)
      options - the entry options; may contain ZipOption.ZIP64
      Returns:
      the nested file for writing entry data (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
      IllegalArgumentException - if ZipOption.DEFLATED is specified
      UnsupportedOperationException - if an unsupported option is specified
    • addBufferedEntry

      public BufferedFile addBufferedEntry(String name, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive that is backed by a nested BufferedFile rather than an output stream. The returned file allows random-access writing of the entry data. The entry is always stored with the STORED method because random-access writing is incompatible with compression. The returned file must be closed before another entry can be added or the archive can be closed. When closed, the CRC-32 is computed from the written data and the local file header is patched with the final CRC and size values.
      Parameters:
      name - the entry name (must not be null)
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Returns:
      the nested file for writing entry data (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
    • addBufferedEntry

      public BufferedFile addBufferedEntry(String name, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a file entry to the archive that is backed by a nested BufferedFile rather than an output stream. The returned file allows random-access writing of the entry data. The entry is always stored with the STORED method because random-access writing is incompatible with compression. The returned file must be closed before another entry can be added or the archive can be closed. When closed, the CRC-32 is computed from the written data and the local file header is patched with the final CRC and size values.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name (must not be null)
      options - the entry options (must not be null); may contain ZipOption.ZIP64
      attrs - optional file attributes for the entry (e.g., POSIX permissions, timestamps)
      Returns:
      the nested file for writing entry data (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
      IllegalArgumentException - if ZipOption.DEFLATED is specified
      UnsupportedOperationException - if an unsupported option is specified
    • addArchive

      public ArchiveBuilder addArchive(String name) throws IOException
      Add a nested archive as a STORED entry in this archive. This is a convenience method that combines addBufferedEntry(String) and open(BufferedFile, OpenOption...) into a single call. The returned archive builder writes to a nested region of the outer archive file. When the returned builder is closed, its central directory is written, then the enclosing entry's CRC-32 and size are computed and patched into the outer local file header.

      The nested builder must be closed before another entry can be added to the outer builder or the outer builder can be closed.

      Usage example

      
       try (ArchiveBuilder outer = ArchiveBuilder.open(path)) {
           try (ArchiveBuilder inner = outer.addArchive("lib/nested.jar")) {
               try (OutputStream os = inner.addEntry("hello.txt")) {
                   os.write(data);
               }
           }
       }
       
      Parameters:
      name - the entry name for the nested archive (must not be null)
      Returns:
      a new archive builder for the nested archive (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
    • addArchive

      public ArchiveBuilder addArchive(String name, OpenOption... options) throws IOException
      Add a nested archive as a STORED entry in this archive with the given options. This is a convenience method that combines addBufferedEntry(String, OpenOption...) and open(BufferedFile, OpenOption...) into a single call. The returned archive builder writes to a nested region of the outer archive file. When the returned builder is closed, its central directory is written, then the enclosing entry's CRC-32 and size are computed and patched into the outer local file header.

      The nested builder must be closed before another entry can be added to the outer builder or the outer builder can be closed.

      ZipOption.ZIP64 applies to the outer entry (reserving ZIP64 space in the outer local file header). The inner builder inherits the same options as its defaults.

      Parameters:
      name - the entry name for the nested archive (must not be null)
      options - the options; may contain ZipOption values
      Returns:
      a new archive builder for the nested archive (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
      UnsupportedOperationException - if an unsupported option is specified
    • addArchive

      public ArchiveBuilder addArchive(String name, FileAttribute<?>... attrs) throws IOException
      Add a nested archive as a STORED entry in this archive with the given file attributes. This is a convenience method that combines addBufferedEntry(String, FileAttribute[]) and open(BufferedFile, OpenOption...) into a single call. The returned archive builder writes to a nested region of the outer archive file. When the returned builder is closed, its central directory is written, then the enclosing entry's CRC-32 and size are computed and patched into the outer local file header.

      The nested builder must be closed before another entry can be added to the outer builder or the outer builder can be closed.

      Parameters:
      name - the entry name for the nested archive (must not be null)
      attrs - optional file attributes for the outer entry (e.g., POSIX permissions, timestamps)
      Returns:
      a new archive builder for the nested archive (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
    • addArchive

      public ArchiveBuilder addArchive(String name, Collection<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException
      Add a nested archive as a STORED entry in this archive with the given options and file attributes. This is a convenience method that combines addBufferedEntry(String, Collection, FileAttribute[]) and open(BufferedFile, OpenOption...) into a single call. The returned archive builder writes to a nested region of the outer archive file. When the returned builder is closed, its central directory is written, then the enclosing entry's CRC-32 and size are computed and patched into the outer local file header.

      The nested builder must be closed before another entry can be added to the outer builder or the outer builder can be closed.

      ZipOption.ZIP64 applies to the outer entry (reserving ZIP64 space in the outer local file header). The inner builder inherits the same options as its defaults. ZipOption.DEFLATED is permitted here (unlike addBufferedEntry) and sets the inner builder's default compression method; the outer entry is always STORED.

      CREATE, CREATE_NEW, READ, WRITE, and TRUNCATE_EXISTING are accepted but ignored, since entries are always created within the archive.

      Parameters:
      name - the entry name for the nested archive (must not be null)
      options - the options (must not be null); may contain ZipOption values
      attrs - optional file attributes for the outer entry (e.g., POSIX permissions, timestamps)
      Returns:
      a new archive builder for the nested archive (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written, or this builder is closed
      UnsupportedOperationException - if an unsupported option is specified
    • addRawData

      public OutputStream addRawData() throws IOException
      Begin writing raw (non-entry) data to the archive file and return an OutputStream for the data. The data is written directly to the underlying file with no local file header, compression, or central directory entry. This is intended for bootstrappers or other tools that hard-code file offsets (obtained from position()) to access opaque binary blobs embedded in the archive.

      The returned stream must be closed before another entry or raw data section can be added, or the archive can be closed.

      Returns:
      an output stream to which the raw data should be written (not null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry or raw data stream is still open, or this builder is closed
    • addRawData

      public void addRawData(InputStream content) throws IOException
      Write raw (non-entry) data to the archive file, reading all bytes from the given input stream. All bytes are read using InputStream.transferTo(OutputStream). The input stream is not closed by this method.

      The data is written directly to the underlying file with no local file header, compression, or central directory entry. This is intended for bootstrappers or other tools that hard-code file offsets (obtained from position()) to access opaque binary blobs embedded in the archive.

      Parameters:
      content - the input stream to read from (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry or raw data stream is still open, or this builder is closed
    • addRawData

      public void addRawData(byte[] data) throws IOException
      Write raw (non-entry) data to the archive file from the given byte array.

      The data is written directly to the underlying file with no local file header, compression, or central directory entry. This is intended for bootstrappers or other tools that hard-code file offsets (obtained from position()) to access opaque binary blobs embedded in the archive.

      Parameters:
      data - the byte array to write (must not be null)
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry or raw data stream is still open, or this builder is closed
    • addRawData

      public void addRawData(byte[] data, int offset, int length) throws IOException
      Write raw (non-entry) data to the archive file from a region of the given byte array.

      The data is written directly to the underlying file with no local file header, compression, or central directory entry. This is intended for bootstrappers or other tools that hard-code file offsets (obtained from position()) to access opaque binary blobs embedded in the archive.

      Parameters:
      data - the byte array to write from (must not be null)
      offset - the start offset in the array
      length - the number of bytes to write
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry or raw data stream is still open, or this builder is closed
      IndexOutOfBoundsException - if offset or length is negative, or offset + length exceeds the array length
    • close

      public void close() throws IOException
      Close this archive builder, writing the central directory and end-of-central-directory records.
      Specified by:
      close in interface AutoCloseable
      Specified by:
      close in interface Closeable
      Throws:
      IOException - if an I/O error occurs
      IllegalStateException - if an entry is still being written