1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/io/FileInputStream.java Thu Oct 03 15:40:35 2013 +0200
1.3 @@ -0,0 +1,408 @@
1.4 +/*
1.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.io;
1.30 +
1.31 +import java.nio.channels.FileChannel;
1.32 +import sun.nio.ch.FileChannelImpl;
1.33 +
1.34 +
1.35 +/**
1.36 + * A <code>FileInputStream</code> obtains input bytes
1.37 + * from a file in a file system. What files
1.38 + * are available depends on the host environment.
1.39 + *
1.40 + * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
1.41 + * such as image data. For reading streams of characters, consider using
1.42 + * <code>FileReader</code>.
1.43 + *
1.44 + * @author Arthur van Hoff
1.45 + * @see java.io.File
1.46 + * @see java.io.FileDescriptor
1.47 + * @see java.io.FileOutputStream
1.48 + * @see java.nio.file.Files#newInputStream
1.49 + * @since JDK1.0
1.50 + */
1.51 +public
1.52 +class FileInputStream extends InputStream
1.53 +{
1.54 + /* File Descriptor - handle to the open file */
1.55 + private final FileDescriptor fd;
1.56 +
1.57 + private FileChannel channel = null;
1.58 +
1.59 + private final Object closeLock = new Object();
1.60 + private volatile boolean closed = false;
1.61 +
1.62 + private static final ThreadLocal<Boolean> runningFinalize =
1.63 + new ThreadLocal<>();
1.64 +
1.65 + private static boolean isRunningFinalize() {
1.66 + Boolean val;
1.67 + if ((val = runningFinalize.get()) != null)
1.68 + return val.booleanValue();
1.69 + return false;
1.70 + }
1.71 +
1.72 + /**
1.73 + * Creates a <code>FileInputStream</code> by
1.74 + * opening a connection to an actual file,
1.75 + * the file named by the path name <code>name</code>
1.76 + * in the file system. A new <code>FileDescriptor</code>
1.77 + * object is created to represent this file
1.78 + * connection.
1.79 + * <p>
1.80 + * First, if there is a security
1.81 + * manager, its <code>checkRead</code> method
1.82 + * is called with the <code>name</code> argument
1.83 + * as its argument.
1.84 + * <p>
1.85 + * If the named file does not exist, is a directory rather than a regular
1.86 + * file, or for some other reason cannot be opened for reading then a
1.87 + * <code>FileNotFoundException</code> is thrown.
1.88 + *
1.89 + * @param name the system-dependent file name.
1.90 + * @exception FileNotFoundException if the file does not exist,
1.91 + * is a directory rather than a regular file,
1.92 + * or for some other reason cannot be opened for
1.93 + * reading.
1.94 + * @exception SecurityException if a security manager exists and its
1.95 + * <code>checkRead</code> method denies read access
1.96 + * to the file.
1.97 + * @see java.lang.SecurityManager#checkRead(java.lang.String)
1.98 + */
1.99 + public FileInputStream(String name) throws FileNotFoundException {
1.100 + this(name != null ? new File(name) : null);
1.101 + }
1.102 +
1.103 + /**
1.104 + * Creates a <code>FileInputStream</code> by
1.105 + * opening a connection to an actual file,
1.106 + * the file named by the <code>File</code>
1.107 + * object <code>file</code> in the file system.
1.108 + * A new <code>FileDescriptor</code> object
1.109 + * is created to represent this file connection.
1.110 + * <p>
1.111 + * First, if there is a security manager,
1.112 + * its <code>checkRead</code> method is called
1.113 + * with the path represented by the <code>file</code>
1.114 + * argument as its argument.
1.115 + * <p>
1.116 + * If the named file does not exist, is a directory rather than a regular
1.117 + * file, or for some other reason cannot be opened for reading then a
1.118 + * <code>FileNotFoundException</code> is thrown.
1.119 + *
1.120 + * @param file the file to be opened for reading.
1.121 + * @exception FileNotFoundException if the file does not exist,
1.122 + * is a directory rather than a regular file,
1.123 + * or for some other reason cannot be opened for
1.124 + * reading.
1.125 + * @exception SecurityException if a security manager exists and its
1.126 + * <code>checkRead</code> method denies read access to the file.
1.127 + * @see java.io.File#getPath()
1.128 + * @see java.lang.SecurityManager#checkRead(java.lang.String)
1.129 + */
1.130 + public FileInputStream(File file) throws FileNotFoundException {
1.131 + String name = (file != null ? file.getPath() : null);
1.132 + SecurityManager security = System.getSecurityManager();
1.133 + if (security != null) {
1.134 + security.checkRead(name);
1.135 + }
1.136 + if (name == null) {
1.137 + throw new NullPointerException();
1.138 + }
1.139 + fd = new FileDescriptor();
1.140 + fd.incrementAndGetUseCount();
1.141 + open(name);
1.142 + }
1.143 +
1.144 + /**
1.145 + * Creates a <code>FileInputStream</code> by using the file descriptor
1.146 + * <code>fdObj</code>, which represents an existing connection to an
1.147 + * actual file in the file system.
1.148 + * <p>
1.149 + * If there is a security manager, its <code>checkRead</code> method is
1.150 + * called with the file descriptor <code>fdObj</code> as its argument to
1.151 + * see if it's ok to read the file descriptor. If read access is denied
1.152 + * to the file descriptor a <code>SecurityException</code> is thrown.
1.153 + * <p>
1.154 + * If <code>fdObj</code> is null then a <code>NullPointerException</code>
1.155 + * is thrown.
1.156 + * <p>
1.157 + * This constructor does not throw an exception if <code>fdObj</code>
1.158 + * is {@link java.io.FileDescriptor#valid() invalid}.
1.159 + * However, if the methods are invoked on the resulting stream to attempt
1.160 + * I/O on the stream, an <code>IOException</code> is thrown.
1.161 + *
1.162 + * @param fdObj the file descriptor to be opened for reading.
1.163 + * @throws SecurityException if a security manager exists and its
1.164 + * <code>checkRead</code> method denies read access to the
1.165 + * file descriptor.
1.166 + * @see SecurityManager#checkRead(java.io.FileDescriptor)
1.167 + */
1.168 + public FileInputStream(FileDescriptor fdObj) {
1.169 + SecurityManager security = System.getSecurityManager();
1.170 + if (fdObj == null) {
1.171 + throw new NullPointerException();
1.172 + }
1.173 + if (security != null) {
1.174 + security.checkRead(fdObj);
1.175 + }
1.176 + fd = fdObj;
1.177 +
1.178 + /*
1.179 + * FileDescriptor is being shared by streams.
1.180 + * Ensure that it's GC'ed only when all the streams/channels are done
1.181 + * using it.
1.182 + */
1.183 + fd.incrementAndGetUseCount();
1.184 + }
1.185 +
1.186 + /**
1.187 + * Opens the specified file for reading.
1.188 + * @param name the name of the file
1.189 + */
1.190 + private native void open(String name) throws FileNotFoundException;
1.191 +
1.192 + /**
1.193 + * Reads a byte of data from this input stream. This method blocks
1.194 + * if no input is yet available.
1.195 + *
1.196 + * @return the next byte of data, or <code>-1</code> if the end of the
1.197 + * file is reached.
1.198 + * @exception IOException if an I/O error occurs.
1.199 + */
1.200 + public native int read() throws IOException;
1.201 +
1.202 + /**
1.203 + * Reads a subarray as a sequence of bytes.
1.204 + * @param b the data to be written
1.205 + * @param off the start offset in the data
1.206 + * @param len the number of bytes that are written
1.207 + * @exception IOException If an I/O error has occurred.
1.208 + */
1.209 + private native int readBytes(byte b[], int off, int len) throws IOException;
1.210 +
1.211 + /**
1.212 + * Reads up to <code>b.length</code> bytes of data from this input
1.213 + * stream into an array of bytes. This method blocks until some input
1.214 + * is available.
1.215 + *
1.216 + * @param b the buffer into which the data is read.
1.217 + * @return the total number of bytes read into the buffer, or
1.218 + * <code>-1</code> if there is no more data because the end of
1.219 + * the file has been reached.
1.220 + * @exception IOException if an I/O error occurs.
1.221 + */
1.222 + public int read(byte b[]) throws IOException {
1.223 + return readBytes(b, 0, b.length);
1.224 + }
1.225 +
1.226 + /**
1.227 + * Reads up to <code>len</code> bytes of data from this input stream
1.228 + * into an array of bytes. If <code>len</code> is not zero, the method
1.229 + * blocks until some input is available; otherwise, no
1.230 + * bytes are read and <code>0</code> is returned.
1.231 + *
1.232 + * @param b the buffer into which the data is read.
1.233 + * @param off the start offset in the destination array <code>b</code>
1.234 + * @param len the maximum number of bytes read.
1.235 + * @return the total number of bytes read into the buffer, or
1.236 + * <code>-1</code> if there is no more data because the end of
1.237 + * the file has been reached.
1.238 + * @exception NullPointerException If <code>b</code> is <code>null</code>.
1.239 + * @exception IndexOutOfBoundsException If <code>off</code> is negative,
1.240 + * <code>len</code> is negative, or <code>len</code> is greater than
1.241 + * <code>b.length - off</code>
1.242 + * @exception IOException if an I/O error occurs.
1.243 + */
1.244 + public int read(byte b[], int off, int len) throws IOException {
1.245 + return readBytes(b, off, len);
1.246 + }
1.247 +
1.248 + /**
1.249 + * Skips over and discards <code>n</code> bytes of data from the
1.250 + * input stream.
1.251 + *
1.252 + * <p>The <code>skip</code> method may, for a variety of
1.253 + * reasons, end up skipping over some smaller number of bytes,
1.254 + * possibly <code>0</code>. If <code>n</code> is negative, an
1.255 + * <code>IOException</code> is thrown, even though the <code>skip</code>
1.256 + * method of the {@link InputStream} superclass does nothing in this case.
1.257 + * The actual number of bytes skipped is returned.
1.258 + *
1.259 + * <p>This method may skip more bytes than are remaining in the backing
1.260 + * file. This produces no exception and the number of bytes skipped
1.261 + * may include some number of bytes that were beyond the EOF of the
1.262 + * backing file. Attempting to read from the stream after skipping past
1.263 + * the end will result in -1 indicating the end of the file.
1.264 + *
1.265 + * @param n the number of bytes to be skipped.
1.266 + * @return the actual number of bytes skipped.
1.267 + * @exception IOException if n is negative, if the stream does not
1.268 + * support seek, or if an I/O error occurs.
1.269 + */
1.270 + public native long skip(long n) throws IOException;
1.271 +
1.272 + /**
1.273 + * Returns an estimate of the number of remaining bytes that can be read (or
1.274 + * skipped over) from this input stream without blocking by the next
1.275 + * invocation of a method for this input stream. The next invocation might be
1.276 + * the same thread or another thread. A single read or skip of this
1.277 + * many bytes will not block, but may read or skip fewer bytes.
1.278 + *
1.279 + * <p> In some cases, a non-blocking read (or skip) may appear to be
1.280 + * blocked when it is merely slow, for example when reading large
1.281 + * files over slow networks.
1.282 + *
1.283 + * @return an estimate of the number of remaining bytes that can be read
1.284 + * (or skipped over) from this input stream without blocking.
1.285 + * @exception IOException if this file input stream has been closed by calling
1.286 + * {@code close} or an I/O error occurs.
1.287 + */
1.288 + public native int available() throws IOException;
1.289 +
1.290 + /**
1.291 + * Closes this file input stream and releases any system resources
1.292 + * associated with the stream.
1.293 + *
1.294 + * <p> If this stream has an associated channel then the channel is closed
1.295 + * as well.
1.296 + *
1.297 + * @exception IOException if an I/O error occurs.
1.298 + *
1.299 + * @revised 1.4
1.300 + * @spec JSR-51
1.301 + */
1.302 + public void close() throws IOException {
1.303 + synchronized (closeLock) {
1.304 + if (closed) {
1.305 + return;
1.306 + }
1.307 + closed = true;
1.308 + }
1.309 + if (channel != null) {
1.310 + /*
1.311 + * Decrement the FD use count associated with the channel
1.312 + * The use count is incremented whenever a new channel
1.313 + * is obtained from this stream.
1.314 + */
1.315 + fd.decrementAndGetUseCount();
1.316 + channel.close();
1.317 + }
1.318 +
1.319 + /*
1.320 + * Decrement the FD use count associated with this stream
1.321 + */
1.322 + int useCount = fd.decrementAndGetUseCount();
1.323 +
1.324 + /*
1.325 + * If FileDescriptor is still in use by another stream, the finalizer
1.326 + * will not close it.
1.327 + */
1.328 + if ((useCount <= 0) || !isRunningFinalize()) {
1.329 + close0();
1.330 + }
1.331 + }
1.332 +
1.333 + /**
1.334 + * Returns the <code>FileDescriptor</code>
1.335 + * object that represents the connection to
1.336 + * the actual file in the file system being
1.337 + * used by this <code>FileInputStream</code>.
1.338 + *
1.339 + * @return the file descriptor object associated with this stream.
1.340 + * @exception IOException if an I/O error occurs.
1.341 + * @see java.io.FileDescriptor
1.342 + */
1.343 + public final FileDescriptor getFD() throws IOException {
1.344 + if (fd != null) return fd;
1.345 + throw new IOException();
1.346 + }
1.347 +
1.348 + /**
1.349 + * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
1.350 + * object associated with this file input stream.
1.351 + *
1.352 + * <p> The initial {@link java.nio.channels.FileChannel#position()
1.353 + * </code>position<code>} of the returned channel will be equal to the
1.354 + * number of bytes read from the file so far. Reading bytes from this
1.355 + * stream will increment the channel's position. Changing the channel's
1.356 + * position, either explicitly or by reading, will change this stream's
1.357 + * file position.
1.358 + *
1.359 + * @return the file channel associated with this file input stream
1.360 + *
1.361 + * @since 1.4
1.362 + * @spec JSR-51
1.363 + */
1.364 + public FileChannel getChannel() {
1.365 + synchronized (this) {
1.366 + if (channel == null) {
1.367 + channel = FileChannelImpl.open(fd, true, false, this);
1.368 +
1.369 + /*
1.370 + * Increment fd's use count. Invoking the channel's close()
1.371 + * method will result in decrementing the use count set for
1.372 + * the channel.
1.373 + */
1.374 + fd.incrementAndGetUseCount();
1.375 + }
1.376 + return channel;
1.377 + }
1.378 + }
1.379 +
1.380 + private static native void initIDs();
1.381 +
1.382 + private native void close0() throws IOException;
1.383 +
1.384 + static {
1.385 + initIDs();
1.386 + }
1.387 +
1.388 + /**
1.389 + * Ensures that the <code>close</code> method of this file input stream is
1.390 + * called when there are no more references to it.
1.391 + *
1.392 + * @exception IOException if an I/O error occurs.
1.393 + * @see java.io.FileInputStream#close()
1.394 + */
1.395 + protected void finalize() throws IOException {
1.396 + if ((fd != null) && (fd != FileDescriptor.in)) {
1.397 +
1.398 + /*
1.399 + * Finalizer should not release the FileDescriptor if another
1.400 + * stream is still using it. If the user directly invokes
1.401 + * close() then the FileDescriptor is also released.
1.402 + */
1.403 + runningFinalize.set(Boolean.TRUE);
1.404 + try {
1.405 + close();
1.406 + } finally {
1.407 + runningFinalize.set(Boolean.FALSE);
1.408 + }
1.409 + }
1.410 + }
1.411 +}