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

de.schlichtherle.io.FileOutputStream Maven / Gradle / Ivy

/*
 * Copyright (C) 2005-2010 Schlichtherle IT Services
 *
 * 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.
 */

package de.schlichtherle.io;

import de.schlichtherle.io.ArchiveController.*;

import java.io.*;

/**
 * A drop-in replacement for {@link java.io.FileOutputStream} which
 * provides transparent write access to archive entries as if they were
 * (virtual) files.
 * All file system operations in this class are
 * virtually atomic.
 * 

* To prevent exceptions to be thrown subsequently, client applications * should always close their streams using the following idiom: *

{@code 
 * FileOutputStream fos = new FileOutputStream(file);
 * try {
 *     // access fos here
 * } finally {
 *     fos.close();
 * }
 * }
*

* Note that for various (mostly archive driver specific) reasons, the * {@code close()} method may throw an {@code IOException}, too. * Client applications need to deal with this appropriately, for example * by enclosing the entire block with another {@code try-catch}-block. *

* Client applications cannot write to an entry in an archive file if an * automatic update is required but cannot get performed because other * {@code FileInputStream} or {@code FileOutputStream} instances * haven't been closed or garbage collected yet. * A {@link FileBusyException} is thrown by the constructors of this class * in this case. *

* Whether or not a client application can write to more than one entry * in the same archive archive file concurrently is an implementation * detail of the respective archive driver. * As of version 6.5, all archive drivers provided by TrueZIP don't restrict * this. * However, custom archive drivers provided by third parties may do so. *

* If a client application tries to exceed the number of entry streams * supported to operate on the same archive file concurrently, a * {@link FileBusyException} is thrown by the constructors of this class. *

* If you would like to use this class in order to copy files, * please consider using the {@code *copy*} methods in the {@link File} * class instead. * These methods provide ease of use, enhanced features, superior performance * and require less space in the temp file folder. * * @see Using Archive Entry Streams * @see FileBusyException * @see File#cat * @see File#umount * @see File#update * @see File#setLenient * @author Christian Schlichtherle * @version $Id: FileOutputStream.java,v 1.4 2010/08/20 13:09:42 christian_schlichtherle Exp $ */ public class FileOutputStream extends FilterOutputStream { /** * Behaves like the super class, but also supports archive entry files. * * @throws FileBusyException If the path denotes an archive entry and the * archive driver does not support to create an additional output * stream for the archive file. * @throws FileNotFoundException On any other I/O related issue. */ public FileOutputStream(String name) throws FileNotFoundException { super(createOutputStream( File.getDefaultArchiveDetector().createFile(name), false)); } /** * Behaves like the super class, but also supports archive entry files. * * @throws FileBusyException If the path denotes an archive entry and the * archive driver does not support to create an additional output * stream for the archive file. * @throws FileNotFoundException On any other I/O related issue. */ public FileOutputStream(String name, boolean append) throws FileNotFoundException { super(createOutputStream( File.getDefaultArchiveDetector().createFile(name), append)); } /** * Behaves like the super class, but also supports archive entry files. * * @throws FileBusyException If the path denotes an archive entry and the * archive driver does not support to create an additional output * stream for the archive file. * @throws FileNotFoundException On any other I/O related issue. */ public FileOutputStream(java.io.File file) throws FileNotFoundException { super(createOutputStream(file, false)); } /** * Behaves like the super class, but also supports archive entry files. * * @throws FileBusyException If the path denotes an archive entry and the * archive driver does not support to create an additional output * stream for the archive file. * @throws FileNotFoundException On any other I/O related issue. */ public FileOutputStream(java.io.File file, boolean append) throws FileNotFoundException { super(createOutputStream(file, append)); } /** * Behaves like the super class. * * @throws FileBusyException If the path denotes an archive entry and the * archive driver does not support to create an additional output * stream for the archive file. * @since TrueZIP 6.4 */ public FileOutputStream(FileDescriptor fd) { super(new java.io.FileOutputStream(fd)); } private static OutputStream createOutputStream( final java.io.File file, final boolean append) throws FileNotFoundException { try { if (file instanceof File) { final File smartFile = (File) file; smartFile.ensureNotVirtualRoot("cannot write"); final File archive = smartFile.getEnclArchive(); final String entryName = smartFile.getEnclEntryName(); assert (archive != null) == (entryName != null); if (archive != null) return archive.getArchiveController() .createOutputStream(entryName, append); } } catch (RfsEntryFalsePositiveException isNotArchive) { } return new java.io.FileOutputStream(file, append); } public void write(byte[] buf, int off, int len) throws IOException { out.write(buf, off, len); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy