Copyright (c) 2000, 2014 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation James Blackburn (Broadcom Corp.) - ongoing development
/******************************************************************************* * Copyright (c) 2000, 2014 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * James Blackburn (Broadcom Corp.) - ongoing development *******************************************************************************/
package org.eclipse.core.internal.localstore; import java.io.*; import org.eclipse.core.internal.utils.FileUtil;
Appends data, in chunks, to a file. Each chunk is defined by the moment the stream is opened (created) and a call to #succeed is made. It is necessary to use the SafeChunkyInputStream to read its contents back. The user of this class does not need to know explicitly about its chunk implementation. It is only an implementation detail. What really matters to the outside world is that it tries to keep the file data consistent. If some data becomes corrupted while writing or later, upon reading the file, the chunk that contains the corrupted data is skipped.

Because of this class purpose (keep data consistent), it is important that the user only calls #succeed when the chunk of data is successfully written. After this call, the user can continue writing data to the file and it will not be considered related to the previous chunk. So, if this data is corrupted, the previous one is still safe.

See Also:
  • SafeChunkyInputStream
/** * Appends data, in chunks, to a file. Each chunk is defined by the moment * the stream is opened (created) and a call to #succeed is made. It is * necessary to use the <code>SafeChunkyInputStream</code> to read its * contents back. The user of this class does not need to know explicitly about * its chunk implementation. * It is only an implementation detail. What really matters to the outside * world is that it tries to keep the file data consistent. * If some data becomes corrupted while writing or later, upon reading * the file, the chunk that contains the corrupted data is skipped. * <p> * Because of this class purpose (keep data consistent), it is important that the * user only calls <code>#succeed</code> when the chunk of data is successfully * written. After this call, the user can continue writing data to the file and it * will not be considered related to the previous chunk. So, if this data is * corrupted, the previous one is still safe. * * @see SafeChunkyInputStream */
public class SafeChunkyOutputStream extends FilterOutputStream { protected String filePath; protected boolean isOpen; public SafeChunkyOutputStream(File target) throws IOException { this(target.getAbsolutePath()); } public SafeChunkyOutputStream(String filePath) throws IOException { super(new BufferedOutputStream(new FileOutputStream(filePath, true))); this.filePath = filePath; isOpen = true; beginChunk(); } protected void beginChunk() throws IOException { write(ILocalStoreConstants.BEGIN_CHUNK); } protected void endChunk() throws IOException { write(ILocalStoreConstants.END_CHUNK); } protected void open() throws IOException { out = new BufferedOutputStream(new FileOutputStream(filePath, true)); isOpen = true; beginChunk(); } public void succeed() throws IOException { try { endChunk(); close(); } finally { isOpen = false; FileUtil.safeClose(this); } }
Overrides super implementation to allow multiple calls on Java 9+. See https://bugs.eclipse.org/bugs/show_bug.cgi?id=530330 {@inheritDoc}
/** * Overrides super implementation to allow multiple calls on Java 9+. * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=530330 * * {@inheritDoc} */
@Override public void close() throws IOException { try (OutputStream ostream = out) { flush(); } } @Override public void write(int b) throws IOException { if (!isOpen) open(); super.write(b); } }