code: public static void archiveFile(@NotNull final ArchiveOutputStream out,
                                     @NotNull final VirtualFileDescriptor source,
                                     final long fileSize) throws IOException {
          if (!source.hasContent()) {
              throw new IllegalArgumentException("Provided source is not a file: " + source.getPath());
          }
          //noinspection ChainOfInstanceofChecks
          if (out instanceof TarArchiveOutputStream) {
              final TarArchiveEntry entry = new TarArchiveEntry(source.getPath() + source.getName());
              entry.setSize(fileSize);
              entry.setModTime(source.getTimeStamp());
              out.putArchiveEntry(entry);
          } else if (out instanceof ZipArchiveOutputStream) {
              final ZipArchiveEntry entry = new ZipArchiveEntry(source.getPath() + source.getName());
              entry.setSize(fileSize);
              entry.setTime(source.getTimeStamp());
              out.putArchiveEntry(entry);
          } else {
              throw new IOException("Unknown archive output stream");
          }
          final InputStream input = source.getInputStream();
          try {
              IOUtil.copyStreams(input, fileSize, out, IOUtil.BUFFER_ALLOCATOR);
          } finally {
              if (source.shouldCloseStream()) {
                  input.close();
              }
          }
          out.closeArchiveEntry();
      }
docs: Adds the file to the tar archive represented by output stream. It's caller's responsibility to close output stream
  properly.
  
  @param out      target archive.
  @param source   file to be added.
  @param fileSize size of the file (which is known in most cases).
  @throws IOException in case of any issues with underlying store.