de.fhg.iais.commons.stream.AutoFileOutputStream.java Source code

Java tutorial

Introduction

Here is the source code for de.fhg.iais.commons.stream.AutoFileOutputStream.java

Source

package de.fhg.iais.commons.stream;

/******************************************************************************
 * Copyright 2011 (c) Fraunhofer IAIS Netmedia  http://www.iais.fraunhofer.de *
 * ************************************************************************** *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License.                   *
 * You may obtain a copy of the License at                                    *
 * http://www.apache.org/licenses/LICENSE-2.0                                 *
 * Unless required by applicable law or agreed to in writing,                 *
 * software distributed under the License is distributed on an "AS IS" BASIS, *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 ******************************************************************************/

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Extended {@link FileOutputStream} that deletes the file if the {@code close} or the {@code onFinally} method is called before the {@code closeAsCompleted} or
 * the {@code setCompleted} method.
 * 
 * @author hjh
 */
public class AutoFileOutputStream extends OutputStreamWithFile implements NeedsFinally {
    private static final Logger LOGGER = LoggerFactory.getLogger(AutoFileOutputStream.class);
    private boolean completed = false;
    private boolean closed = false;
    private boolean done = false;
    private static final boolean DOWARNING = true;

    public AutoFileOutputStream(String name, boolean append) throws FileNotFoundException {
        super(name, append);
    }

    public void setCompleted() {
        this.completed = true;
    }

    public final void closeAsCompleted() throws IOException {
        doClose(true);
        this.completed = true;
    }

    @Override
    public final void close() throws IOException {
        doClose(this.completed);
    }

    private final void doClose(boolean completed) throws IOException {
        if (!this.done) {
            IOException exception = this.closed ? null : internalClose();
            this.done = postClose(completed, exception);

            if (exception != null) {
                throw exception;
            }
        }
    }

    private final IOException internalClose() {
        try {
            super.close();
            return null;
        } catch (IOException e) {
            return e;
        } finally {
            this.closed = true;
        }
    }

    protected boolean postClose(boolean completed, IOException exception) throws IOException {
        if (!completed) {
            File f = getFile();

            if (!deleteFile(f) && AutoFileOutputStream.DOWARNING) {
                LOGGER.warn("Can't delete incomplete file \"{}\" - it will continue to exist", f.getAbsolutePath());
                return false;
            }
        }

        return true;
    }

    private static boolean deleteFile(File f) {
        return (f == null) || f.delete() || !f.exists();
    }

    //    public boolean isCompleted() {
    //        return this.completed;
    //    }

    @Override
    protected void finalize() throws IOException {
        onFinally();
        super.finalize();
    }

    @Override
    public void onFinally() {
        IOUtils.closeQuietly(this);
    }

}