All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.osgi.framework.internal.reliablefile.ReliableFileOutputStream Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright (c) 2003, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.osgi.framework.internal.reliablefile;

import java.io.*;
import java.util.zip.Checksum;

/**
 * A ReliableFile FileOutputStream replacement class.
 * This class can be used just like FileOutputStream. The class
 * is in partnership with ReliableFileInputStream to avoid losing
 * file data by using multiple files.
 *
 * @see			ReliableFileInputStream
 */
public class ReliableFileOutputStream extends FilterOutputStream {
	/**
	 * ReliableFile object for the file.
	 */
	private ReliableFile reliable;

	/**
	 * Checksum calculator
	 */
	private Checksum crc;

	private boolean outputOpen = false;

	/**
	 * Constructs a new ReliableFileOutputStream on the File file.  If the
	 * file exists, it is written over.  See the constructor which can append to
	 * the file if so desired.
	 *
	 * @param		file		the File on which to stream reads.
	 * @exception 	java.io.IOException If an error occurs opening the file.
	 */
	public ReliableFileOutputStream(File file) throws IOException {
		this(ReliableFile.getReliableFile(file), false);
	}

	/**
	 * Constructs a new ReliableFileOutputStream on the File file.
	 *
	 * @param		file		the File on which to stream reads.
	 * @param		append		a boolean indicating whether or not to append to an existing file.
	 * @exception 	java.io.IOException If an error occurs opening the file.
	 */
	public ReliableFileOutputStream(File file, boolean append) throws IOException {
		this(ReliableFile.getReliableFile(file), append);
	}

	/**
	 * Constructs a new ReliableFileOutputStream on the file named name. If
	 * the file exists, it is written over.  See the constructor which can append to
	 * the file if so desired.
	 * The name may be absolute or relative
	 * to the System property "user.dir".
	 *
	 * @param		name	the file on which to stream writes.
	 * @exception 	java.io.IOException If an error occurs opening the file.
	 */
	public ReliableFileOutputStream(String name) throws IOException {
		this(ReliableFile.getReliableFile(name), false);
	}

	/**
	 * Constructs a new ReliableFileOutputStream on the file named name.
	 * The name may be absolute or relative
	 * to the System property "user.dir".
	 *
	 * @param		name	the file on which to stream writes.
	 * @param		append		a boolean indicating whether or not to append to an existing file.
	 * @exception 	java.io.IOException If an error occurs opening the file.
	 */
	public ReliableFileOutputStream(String name, boolean append) throws IOException {
		this(ReliableFile.getReliableFile(name), append);
	}

	/**
	 * Private constructor used by other constructors.
	 *
	 * @param		reliable		the ReliableFile on which to read.
	 * @param		append		a boolean indicating whether or not to append to an existing file.
	 * @exception 	java.io.IOException If an error occurs opening the file.
	 */
	private ReliableFileOutputStream(ReliableFile reliable, boolean append) throws IOException {
		super(reliable.getOutputStream(append, ReliableFile.GENERATION_LATEST));

		this.reliable = reliable;
		outputOpen = true;
		if (append)
			crc = reliable.getFileChecksum();
		else
			crc = reliable.getChecksumCalculator();
	}

	/**
	 * Closes this output stream and releases any system resources
	 * associated with this stream. The general contract of close
	 * is that it closes the output stream. A closed stream cannot perform
	 * output operations and cannot be reopened.
	 *
	 * @exception 	java.io.IOException If an error occurs closing the file.
	 */
	public synchronized void close() throws IOException {
		closeIntermediateFile();
		reliable.closeOutputFile(crc);
		// if the previouse closeOutpuFile() throws exception,
		//  we don't null out reliable to give another opportunity
		//  to rename the file.
		reliable = null;
	}

	public File closeIntermediateFile() throws IOException {
		if (reliable == null)
			throw new IOException("ReliableFile stream not open"); //$NON-NLS-1$
		if (outputOpen) {
			// tag on our signature and checksum
			reliable.writeChecksumSignature(out, crc);
			out.flush();
			try {
				((FileOutputStream) out).getFD().sync();
			} catch (IOException e) {
				// just ignore this Exception
				//Debug
				e.printStackTrace();
			}
			out.close();
			outputOpen = false;
		}
		return reliable.getOutputFile();
	}

	/**
	 * Override default FilterOutputStream method.
	 * @see FilterOutputStream#write(byte[])
	 */
	public void write(byte[] b) throws IOException {
		this.write(b, 0, b.length);
	}

	/**
	 * Override default FilterOutputStream method.
	 * @see FilterOutputStream#write(byte[], int, int)
	 */
	public void write(byte[] b, int off, int len) throws IOException {
		out.write(b, off, len);
		crc.update(b, off, len);
	}

	/**
	 * Override default FilterOutputStream method.
	 * @see FilterOutputStream#write(int)
	 */
	public void write(int b) throws IOException {
		out.write(b);
		crc.update((byte) b);
	}

	public void abort() {
		if (reliable == null)
			return;
		if (outputOpen) {
			try {
				out.close();
			} catch (IOException e) {/*ignore*/
			}
			outputOpen = false;
		}
		reliable.abortOutputFile();
		reliable = null;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy