public void save(File file) throws IOException {
    byte[] buff;

    // Archive file
    RandomAccessFile raf= new RandomAccessFile(file, "rw");
    raf.seek(0);

    // Write magic number & format version
    raf.write(XarArchive.MAGIC_NUMBER);
    raf.writeByte(XarArchive.FORMAT_VERSION);

    // Write number of entries
    XarArchive.writeIntLsb(raf, this.entries.size());

    // Write XAR entries
    int ei= 0;
    int offset= 0;
    for (Iterator<XarEntry> it= this.entries.iterator(); it.hasNext(); ) {
      XarEntry entry= it.next();

      // Write name
      raf.seek(XarArchive.HEADER_SIZE + ei * XarArchive.ENTRY_SIZE);
      raf.write(entry.getName().getBytes(XarArchive.ENC_CHARSET));

      // Write size
      raf.seek(XarArchive.HEADER_SIZE + ei * XarArchive.ENTRY_SIZE + XarEntry.NAME_MAXLEN);
      XarArchive.writeIntLsb(raf, entry.getLength());

      // Write offset
      XarArchive.writeIntLsb(raf, offset);
      offset+= entry.getLength();

      // Increment counter
      ei++;
    }

    // Write XAR entries payload
    raf.seek(XarArchive.HEADER_SIZE + this.entries.size() * XarArchive.ENTRY_SIZE);
    buff= new byte[SAVE_BUFFSIZE];
    for (Iterator<XarEntry> it= this.entries.iterator(); it.hasNext(); ) {
      InputStream entryIs= it.next().getInputStream();

      // Read from entry payload input stream and write to .xar file (in chunks of SAVE_BUFFSIZE bytes)
      int bytesRead;
      while ((bytesRead= entryIs.read(buff)) >= 0) {
        raf.write(buff, 0, bytesRead);
      }

      // Close payload input stream
      entryIs.close();
    }

    // Close file
    raf.close();
  }