Path: blob/master/src/java.desktop/share/classes/javax/imageio/stream/FileImageOutputStream.java
41153 views
/*1* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.imageio.stream;2627import java.io.File;28import java.io.FileNotFoundException;29import java.io.IOException;30import java.io.RandomAccessFile;31import com.sun.imageio.stream.CloseableDisposerRecord;32import com.sun.imageio.stream.StreamFinalizer;33import sun.java2d.Disposer;3435/**36* An implementation of {@code ImageOutputStream} that writes its37* output directly to a {@code File} or38* {@code RandomAccessFile}.39*40*/41public class FileImageOutputStream extends ImageOutputStreamImpl {4243private RandomAccessFile raf;4445/** The referent to be registered with the Disposer. */46private final Object disposerReferent;4748/** The DisposerRecord that closes the underlying RandomAccessFile. */49private final CloseableDisposerRecord disposerRecord;5051/**52* Constructs a {@code FileImageOutputStream} that will write53* to a given {@code File}.54*55* @param f a {@code File} to write to.56*57* @exception IllegalArgumentException if {@code f} is58* {@code null}.59* @exception SecurityException if a security manager exists60* and does not allow write access to the file.61* @exception FileNotFoundException if {@code f} does not denote62* a regular file or it cannot be opened for reading and writing for any63* other reason.64* @exception IOException if an I/O error occurs.65*/66public FileImageOutputStream(File f)67throws FileNotFoundException, IOException {68this(f == null ? null : new RandomAccessFile(f, "rw"));69}7071/**72* Constructs a {@code FileImageOutputStream} that will write73* to a given {@code RandomAccessFile}.74*75* @param raf a {@code RandomAccessFile} to write to.76*77* @exception IllegalArgumentException if {@code raf} is78* {@code null}.79*/80public FileImageOutputStream(RandomAccessFile raf) {81if (raf == null) {82throw new IllegalArgumentException("raf == null!");83}84this.raf = raf;8586disposerRecord = new CloseableDisposerRecord(raf);87if (getClass() == FileImageOutputStream.class) {88disposerReferent = new Object();89Disposer.addRecord(disposerReferent, disposerRecord);90} else {91disposerReferent = new StreamFinalizer(this);92}93}9495public int read() throws IOException {96checkClosed();97bitOffset = 0;98int val = raf.read();99if (val != -1) {100++streamPos;101}102return val;103}104105public int read(byte[] b, int off, int len) throws IOException {106checkClosed();107bitOffset = 0;108int nbytes = raf.read(b, off, len);109if (nbytes != -1) {110streamPos += nbytes;111}112return nbytes;113}114115public void write(int b) throws IOException {116flushBits(); // this will call checkClosed() for us117raf.write(b);118++streamPos;119}120121public void write(byte[] b, int off, int len) throws IOException {122flushBits(); // this will call checkClosed() for us123raf.write(b, off, len);124streamPos += len;125}126127public long length() {128try {129checkClosed();130return raf.length();131} catch (IOException e) {132return -1L;133}134}135136/**137* Sets the current stream position and resets the bit offset to138* 0. It is legal to seeking past the end of the file; an139* {@code EOFException} will be thrown only if a read is140* performed. The file length will not be increased until a write141* is performed.142*143* @exception IndexOutOfBoundsException if {@code pos} is smaller144* than the flushed position.145* @exception IOException if any other I/O error occurs.146*/147public void seek(long pos) throws IOException {148checkClosed();149if (pos < flushedPos) {150throw new IndexOutOfBoundsException("pos < flushedPos!");151}152bitOffset = 0;153raf.seek(pos);154streamPos = raf.getFilePointer();155}156157public void close() throws IOException {158super.close();159disposerRecord.dispose(); // this closes the RandomAccessFile160raf = null;161}162163/**164* {@inheritDoc}165*166* @deprecated The {@code finalize} method has been deprecated.167* Subclasses that override {@code finalize} in order to perform cleanup168* should be modified to use alternative cleanup mechanisms and169* to remove the overriding {@code finalize} method.170* When overriding the {@code finalize} method, its implementation must explicitly171* ensure that {@code super.finalize()} is invoked as described in {@link Object#finalize}.172* See the specification for {@link Object#finalize()} for further173* information about migration options.174*/175@Deprecated(since="9")176protected void finalize() throws Throwable {177// Empty finalizer: for performance reasons we instead use the178// Disposer mechanism for ensuring that the underlying179// RandomAccessFile is closed prior to garbage collection180}181}182183184