001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.commons.compress.parallel;
020
021import java.io.File;
022import java.io.FileNotFoundException;
023import java.io.IOException;
024import java.io.InputStream;
025import java.io.OutputStream;
026import java.io.UncheckedIOException;
027import java.nio.file.Files;
028import java.nio.file.Path;
029
030/**
031 * ScatterGatherBackingStore that is backed by a path.
032 *
033 * @since 1.10
034 */
035public class FileBasedScatterGatherBackingStore implements ScatterGatherBackingStore {
036    private final Path target;
037    private final OutputStream outputStream;
038    private boolean closed;
039
040    /**
041     * Constructs a new instance.
042     *
043     * @param target The path to offload compressed data into.
044     * @throws FileNotFoundException if the file doesn't exist.
045     */
046    public FileBasedScatterGatherBackingStore(final File target) throws FileNotFoundException {
047        this(target.toPath());
048    }
049
050    /**
051     * Constructs a new instance for the given path.
052     *
053     * @param target The path to offload compressed data into.
054     * @throws FileNotFoundException if the file doesn't exist.
055     * @since 1.22
056     */
057    public FileBasedScatterGatherBackingStore(final Path target) throws FileNotFoundException {
058        this.target = target;
059        try {
060            outputStream = Files.newOutputStream(target);
061        } catch (final FileNotFoundException ex) {
062            throw ex;
063        } catch (final IOException ex) {
064            // must convert exception to stay backwards compatible with Compress 1.10 to 1.13
065            throw new UncheckedIOException(ex); // NOSONAR
066        }
067    }
068
069    @Override
070    public void close() throws IOException {
071        try {
072            closeForWriting();
073        } finally {
074            Files.deleteIfExists(target);
075        }
076    }
077
078    @Override
079    public void closeForWriting() throws IOException {
080        if (!closed) {
081            outputStream.close();
082            closed = true;
083        }
084    }
085
086    @Override
087    public InputStream getInputStream() throws IOException {
088        return Files.newInputStream(target);
089    }
090
091    @Override
092    public void writeOut(final byte[] data, final int offset, final int length) throws IOException {
093        outputStream.write(data, offset, length);
094    }
095}