Example #1
0
  /**
   * Writes {@linkplain data} and metadata until container is full or stream completes
   *
   * @param container file that will be written to. Must be unsealed and have enough free space for
   *     meta data and >=1 byte of data.
   * @param file contains file meta data known so far
   * @param data (buffered) stream of data to be written
   * @param tailId continuation pointer to use if container is too small
   * @return new file containing ALL meta data
   * @throws WriteFileInContainerException
   */
  public static File write(
      Container container, File file, BufferedInputStream data, long maxLength, long tailId)
      throws WriteFileInContainerException, ContainerFileCorruptedException {
    long beginPos = container.getCurrentSize();
    WriteFileInContainerException error = null;
    ContainerFileCorruptedException seriousError = null;
    try {
      BufferedOutputStream bstream =
          new BufferedOutputStream(new FileOutputStream(container.getFileName(), true));
      DataWriteResult written = null;
      try {
        writePadding(bstream, File.HEADER_SIZE);
        written = writeFileDataAndChecksum(bstream, data, maxLength - File.OVERHEAD_SIZE);
        if (written.isCompleted()) tailId = FileInContainer.NO_TAIL_ID; // we don't need to continue
      } catch (IOException e) {
        error = new WriteFileInContainerException("Unable to write file contents", e);
      } catch (NoSuchAlgorithmException e) {
        error = new WriteFileInContainerException("Unable to find checksum provider", e);
      }
      bstream.close();

      if (error != null) {
        error = new WriteFileInContainerException("Write reverted, nothing written", error);
        try {
          container.truncate(beginPos);
        } catch (TruncateContainerFileException e) {
          seriousError = new ContainerFileCorruptedException("Reverting write failed", e);
        }
      } else {
        file = File.addLocation(file, beginPos, written.getLength(), tailId);
        writeFileHeaders(container, file);
      }
    } catch (FileNotFoundException e) {
      error = new WriteFileInContainerException("Unable to open FileOutputStream", e);
    } catch (IOException e) {
      error = new WriteFileInContainerException("Unable to close FileOutputStream", e);
    } catch (WriteHeaderException e) {
      seriousError = new ContainerFileCorruptedException("Unable to write header", e);
    }

    if (seriousError != null) throw seriousError;
    if (error != null) throw error;

    return file;
  }