Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/imageio/stream/FileImageOutputStream.java
38918 views
/*1* Copyright (c) 2000, 2007, 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</code> that writes its37* output directly to a <code>File</code> or38* <code>RandomAccessFile</code>.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</code> that will write53* to a given <code>File</code>.54*55* @param f a <code>File</code> to write to.56*57* @exception IllegalArgumentException if <code>f</code> is58* <code>null</code>.59* @exception SecurityException if a security manager exists60* and does not allow write access to the file.61* @exception FileNotFoundException if <code>f</code> 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</code> that will write73* to a given <code>RandomAccessFile</code>.74*75* @param raf a <code>RandomAccessFile</code> to write to.76*77* @exception IllegalArgumentException if <code>raf</code> is78* <code>null</code>.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</code> 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</code> 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*/166protected void finalize() throws Throwable {167// Empty finalizer: for performance reasons we instead use the168// Disposer mechanism for ensuring that the underlying169// RandomAccessFile is closed prior to garbage collection170}171}172173174