~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to external/ikvm/openjdk/java/io/FileInputStream.java

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
 
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
4
 *
 
5
 * This code is free software; you can redistribute it and/or modify it
 
6
 * under the terms of the GNU General Public License version 2 only, as
 
7
 * published by the Free Software Foundation.  Oracle designates this
 
8
 * particular file as subject to the "Classpath" exception as provided
 
9
 * by Oracle in the LICENSE file that accompanied this code.
 
10
 *
 
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
 
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
14
 * version 2 for more details (a copy is included in the LICENSE file that
 
15
 * accompanied this code).
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License version
 
18
 * 2 along with this work; if not, write to the Free Software Foundation,
 
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
 *
 
21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 
22
 * or visit www.oracle.com if you need additional information or have any
 
23
 * questions.
 
24
 */
 
25
 
 
26
package java.io;
 
27
 
 
28
import java.nio.channels.FileChannel;
 
29
import sun.nio.ch.FileChannelImpl;
 
30
 
 
31
 
 
32
/**
 
33
 * A <code>FileInputStream</code> obtains input bytes
 
34
 * from a file in a file system. What files
 
35
 * are  available depends on the host environment.
 
36
 *
 
37
 * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
 
38
 * such as image data. For reading streams of characters, consider using
 
39
 * <code>FileReader</code>.
 
40
 *
 
41
 * @author  Arthur van Hoff
 
42
 * @see     java.io.File
 
43
 * @see     java.io.FileDescriptor
 
44
 * @see     java.io.FileOutputStream
 
45
 * @see     java.nio.file.Files#newInputStream
 
46
 * @since   JDK1.0
 
47
 */
 
48
public
 
49
class FileInputStream extends InputStream
 
50
{
 
51
    /* File Descriptor - handle to the open file */
 
52
    private final FileDescriptor fd;
 
53
 
 
54
    private FileChannel channel = null;
 
55
 
 
56
    private final Object closeLock = new Object();
 
57
    private volatile boolean closed = false;
 
58
 
 
59
    private static final ThreadLocal<Boolean> runningFinalize =
 
60
        new ThreadLocal<>();
 
61
 
 
62
    private static boolean isRunningFinalize() {
 
63
        Boolean val;
 
64
        if ((val = runningFinalize.get()) != null)
 
65
            return val.booleanValue();
 
66
        return false;
 
67
    }
 
68
 
 
69
    /**
 
70
     * Creates a <code>FileInputStream</code> by
 
71
     * opening a connection to an actual file,
 
72
     * the file named by the path name <code>name</code>
 
73
     * in the file system.  A new <code>FileDescriptor</code>
 
74
     * object is created to represent this file
 
75
     * connection.
 
76
     * <p>
 
77
     * First, if there is a security
 
78
     * manager, its <code>checkRead</code> method
 
79
     * is called with the <code>name</code> argument
 
80
     * as its argument.
 
81
     * <p>
 
82
     * If the named file does not exist, is a directory rather than a regular
 
83
     * file, or for some other reason cannot be opened for reading then a
 
84
     * <code>FileNotFoundException</code> is thrown.
 
85
     *
 
86
     * @param      name   the system-dependent file name.
 
87
     * @exception  FileNotFoundException  if the file does not exist,
 
88
     *                   is a directory rather than a regular file,
 
89
     *                   or for some other reason cannot be opened for
 
90
     *                   reading.
 
91
     * @exception  SecurityException      if a security manager exists and its
 
92
     *               <code>checkRead</code> method denies read access
 
93
     *               to the file.
 
94
     * @see        java.lang.SecurityManager#checkRead(java.lang.String)
 
95
     */
 
96
    public FileInputStream(String name) throws FileNotFoundException {
 
97
        this(name != null ? new File(name) : null);
 
98
    }
 
99
 
 
100
    /**
 
101
     * Creates a <code>FileInputStream</code> by
 
102
     * opening a connection to an actual file,
 
103
     * the file named by the <code>File</code>
 
104
     * object <code>file</code> in the file system.
 
105
     * A new <code>FileDescriptor</code> object
 
106
     * is created to represent this file connection.
 
107
     * <p>
 
108
     * First, if there is a security manager,
 
109
     * its <code>checkRead</code> method  is called
 
110
     * with the path represented by the <code>file</code>
 
111
     * argument as its argument.
 
112
     * <p>
 
113
     * If the named file does not exist, is a directory rather than a regular
 
114
     * file, or for some other reason cannot be opened for reading then a
 
115
     * <code>FileNotFoundException</code> is thrown.
 
116
     *
 
117
     * @param      file   the file to be opened for reading.
 
118
     * @exception  FileNotFoundException  if the file does not exist,
 
119
     *                   is a directory rather than a regular file,
 
120
     *                   or for some other reason cannot be opened for
 
121
     *                   reading.
 
122
     * @exception  SecurityException      if a security manager exists and its
 
123
     *               <code>checkRead</code> method denies read access to the file.
 
124
     * @see        java.io.File#getPath()
 
125
     * @see        java.lang.SecurityManager#checkRead(java.lang.String)
 
126
     */
 
127
    public FileInputStream(File file) throws FileNotFoundException {
 
128
        String name = (file != null ? file.getPath() : null);
 
129
        SecurityManager security = System.getSecurityManager();
 
130
        if (security != null) {
 
131
            security.checkRead(name);
 
132
        }
 
133
        if (name == null) {
 
134
            throw new NullPointerException();
 
135
        }
 
136
        fd = new FileDescriptor();
 
137
        fd.incrementAndGetUseCount();
 
138
        open(name);
 
139
    }
 
140
 
 
141
    /**
 
142
     * Creates a <code>FileInputStream</code> by using the file descriptor
 
143
     * <code>fdObj</code>, which represents an existing connection to an
 
144
     * actual file in the file system.
 
145
     * <p>
 
146
     * If there is a security manager, its <code>checkRead</code> method is
 
147
     * called with the file descriptor <code>fdObj</code> as its argument to
 
148
     * see if it's ok to read the file descriptor. If read access is denied
 
149
     * to the file descriptor a <code>SecurityException</code> is thrown.
 
150
     * <p>
 
151
     * If <code>fdObj</code> is null then a <code>NullPointerException</code>
 
152
     * is thrown.
 
153
     * <p>
 
154
     * This constructor does not throw an exception if <code>fdObj</code>
 
155
     * is {@link java.io.FileDescriptor#valid() invalid}.
 
156
     * However, if the methods are invoked on the resulting stream to attempt
 
157
     * I/O on the stream, an <code>IOException</code> is thrown.
 
158
     *
 
159
     * @param      fdObj   the file descriptor to be opened for reading.
 
160
     * @throws     SecurityException      if a security manager exists and its
 
161
     *                 <code>checkRead</code> method denies read access to the
 
162
     *                 file descriptor.
 
163
     * @see        SecurityManager#checkRead(java.io.FileDescriptor)
 
164
     */
 
165
    public FileInputStream(FileDescriptor fdObj) {
 
166
        SecurityManager security = System.getSecurityManager();
 
167
        if (fdObj == null) {
 
168
            throw new NullPointerException();
 
169
        }
 
170
        if (security != null) {
 
171
            security.checkRead(fdObj);
 
172
        }
 
173
        fd = fdObj;
 
174
 
 
175
        /*
 
176
         * FileDescriptor is being shared by streams.
 
177
         * Ensure that it's GC'ed only when all the streams/channels are done
 
178
         * using it.
 
179
         */
 
180
        fd.incrementAndGetUseCount();
 
181
    }
 
182
 
 
183
    /**
 
184
     * Opens the specified file for reading.
 
185
     * @param name the name of the file
 
186
     */
 
187
    private void open(String name) throws FileNotFoundException
 
188
    {
 
189
        fd.openReadOnly(name);
 
190
    }
 
191
 
 
192
    /**
 
193
     * Reads a byte of data from this input stream. This method blocks
 
194
     * if no input is yet available.
 
195
     *
 
196
     * @return     the next byte of data, or <code>-1</code> if the end of the
 
197
     *             file is reached.
 
198
     * @exception  IOException  if an I/O error occurs.
 
199
     */
 
200
    public int read() throws IOException
 
201
    {
 
202
        return fd.read();
 
203
    }
 
204
 
 
205
    /**
 
206
     * Reads a subarray as a sequence of bytes.
 
207
     * @param b the data to be written
 
208
     * @param off the start offset in the data
 
209
     * @param len the number of bytes that are written
 
210
     * @exception IOException If an I/O error has occurred.
 
211
     */
 
212
    private int readBytes(byte b[], int off, int len) throws IOException
 
213
    {
 
214
        return fd.readBytes(b, off, len);
 
215
    }
 
216
 
 
217
    /**
 
218
     * Reads up to <code>b.length</code> bytes of data from this input
 
219
     * stream into an array of bytes. This method blocks until some input
 
220
     * is available.
 
221
     *
 
222
     * @param      b   the buffer into which the data is read.
 
223
     * @return     the total number of bytes read into the buffer, or
 
224
     *             <code>-1</code> if there is no more data because the end of
 
225
     *             the file has been reached.
 
226
     * @exception  IOException  if an I/O error occurs.
 
227
     */
 
228
    public int read(byte b[]) throws IOException {
 
229
        return readBytes(b, 0, b.length);
 
230
    }
 
231
 
 
232
    /**
 
233
     * Reads up to <code>len</code> bytes of data from this input stream
 
234
     * into an array of bytes. If <code>len</code> is not zero, the method
 
235
     * blocks until some input is available; otherwise, no
 
236
     * bytes are read and <code>0</code> is returned.
 
237
     *
 
238
     * @param      b     the buffer into which the data is read.
 
239
     * @param      off   the start offset in the destination array <code>b</code>
 
240
     * @param      len   the maximum number of bytes read.
 
241
     * @return     the total number of bytes read into the buffer, or
 
242
     *             <code>-1</code> if there is no more data because the end of
 
243
     *             the file has been reached.
 
244
     * @exception  NullPointerException If <code>b</code> is <code>null</code>.
 
245
     * @exception  IndexOutOfBoundsException If <code>off</code> is negative,
 
246
     * <code>len</code> is negative, or <code>len</code> is greater than
 
247
     * <code>b.length - off</code>
 
248
     * @exception  IOException  if an I/O error occurs.
 
249
     */
 
250
    public int read(byte b[], int off, int len) throws IOException {
 
251
        return readBytes(b, off, len);
 
252
    }
 
253
 
 
254
    /**
 
255
     * Skips over and discards <code>n</code> bytes of data from the
 
256
     * input stream.
 
257
     *
 
258
     * <p>The <code>skip</code> method may, for a variety of
 
259
     * reasons, end up skipping over some smaller number of bytes,
 
260
     * possibly <code>0</code>. If <code>n</code> is negative, an
 
261
     * <code>IOException</code> is thrown, even though the <code>skip</code>
 
262
     * method of the {@link InputStream} superclass does nothing in this case.
 
263
     * The actual number of bytes skipped is returned.
 
264
     *
 
265
     * <p>This method may skip more bytes than are remaining in the backing
 
266
     * file. This produces no exception and the number of bytes skipped
 
267
     * may include some number of bytes that were beyond the EOF of the
 
268
     * backing file. Attempting to read from the stream after skipping past
 
269
     * the end will result in -1 indicating the end of the file.
 
270
     *
 
271
     * @param      n   the number of bytes to be skipped.
 
272
     * @return     the actual number of bytes skipped.
 
273
     * @exception  IOException  if n is negative, if the stream does not
 
274
     *             support seek, or if an I/O error occurs.
 
275
     */
 
276
    public long skip(long n) throws IOException
 
277
    {
 
278
        return fd.skip(n);
 
279
    }
 
280
 
 
281
    /**
 
282
     * Returns an estimate of the number of remaining bytes that can be read (or
 
283
     * skipped over) from this input stream without blocking by the next
 
284
     * invocation of a method for this input stream. The next invocation might be
 
285
     * the same thread or another thread.  A single read or skip of this
 
286
     * many bytes will not block, but may read or skip fewer bytes.
 
287
     *
 
288
     * <p> In some cases, a non-blocking read (or skip) may appear to be
 
289
     * blocked when it is merely slow, for example when reading large
 
290
     * files over slow networks.
 
291
     *
 
292
     * @return     an estimate of the number of remaining bytes that can be read
 
293
     *             (or skipped over) from this input stream without blocking.
 
294
     * @exception  IOException  if this file input stream has been closed by calling
 
295
     *             {@code close} or an I/O error occurs.
 
296
     */
 
297
    public int available() throws IOException
 
298
    {
 
299
        return fd.available();
 
300
    }
 
301
 
 
302
    /**
 
303
     * Closes this file input stream and releases any system resources
 
304
     * associated with the stream.
 
305
     *
 
306
     * <p> If this stream has an associated channel then the channel is closed
 
307
     * as well.
 
308
     *
 
309
     * @exception  IOException  if an I/O error occurs.
 
310
     *
 
311
     * @revised 1.4
 
312
     * @spec JSR-51
 
313
     */
 
314
    public void close() throws IOException {
 
315
        synchronized (closeLock) {
 
316
            if (closed) {
 
317
                return;
 
318
            }
 
319
            closed = true;
 
320
        }
 
321
        if (channel != null) {
 
322
            /*
 
323
             * Decrement the FD use count associated with the channel
 
324
             * The use count is incremented whenever a new channel
 
325
             * is obtained from this stream.
 
326
             */
 
327
           fd.decrementAndGetUseCount();
 
328
           channel.close();
 
329
        }
 
330
 
 
331
        /*
 
332
         * Decrement the FD use count associated with this stream
 
333
         */
 
334
        int useCount = fd.decrementAndGetUseCount();
 
335
 
 
336
        /*
 
337
         * If FileDescriptor is still in use by another stream, the finalizer
 
338
         * will not close it.
 
339
         */
 
340
        if ((useCount <= 0) || !isRunningFinalize()) {
 
341
            close0();
 
342
        }
 
343
    }
 
344
 
 
345
    /**
 
346
     * Returns the <code>FileDescriptor</code>
 
347
     * object  that represents the connection to
 
348
     * the actual file in the file system being
 
349
     * used by this <code>FileInputStream</code>.
 
350
     *
 
351
     * @return     the file descriptor object associated with this stream.
 
352
     * @exception  IOException  if an I/O error occurs.
 
353
     * @see        java.io.FileDescriptor
 
354
     */
 
355
    public final FileDescriptor getFD() throws IOException {
 
356
        if (fd != null) return fd;
 
357
        throw new IOException();
 
358
    }
 
359
 
 
360
    /**
 
361
     * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
 
362
     * object associated with this file input stream.
 
363
     *
 
364
     * <p> The initial {@link java.nio.channels.FileChannel#position()
 
365
     * </code>position<code>} of the returned channel will be equal to the
 
366
     * number of bytes read from the file so far.  Reading bytes from this
 
367
     * stream will increment the channel's position.  Changing the channel's
 
368
     * position, either explicitly or by reading, will change this stream's
 
369
     * file position.
 
370
     *
 
371
     * @return  the file channel associated with this file input stream
 
372
     *
 
373
     * @since 1.4
 
374
     * @spec JSR-51
 
375
     */
 
376
    public FileChannel getChannel() {
 
377
        synchronized (this) {
 
378
            if (channel == null) {
 
379
                channel = FileChannelImpl.open(fd, true, false, this);
 
380
 
 
381
                /*
 
382
                 * Increment fd's use count. Invoking the channel's close()
 
383
                 * method will result in decrementing the use count set for
 
384
                 * the channel.
 
385
                 */
 
386
                fd.incrementAndGetUseCount();
 
387
            }
 
388
            return channel;
 
389
        }
 
390
    }
 
391
 
 
392
    private void close0() throws IOException
 
393
    {
 
394
        fd.close();
 
395
    }
 
396
 
 
397
    /**
 
398
     * Ensures that the <code>close</code> method of this file input stream is
 
399
     * called when there are no more references to it.
 
400
     *
 
401
     * @exception  IOException  if an I/O error occurs.
 
402
     * @see        java.io.FileInputStream#close()
 
403
     */
 
404
    protected void finalize() throws IOException {
 
405
        if ((fd != null) &&  (fd != FileDescriptor.in)) {
 
406
 
 
407
            /*
 
408
             * Finalizer should not release the FileDescriptor if another
 
409
             * stream is still using it. If the user directly invokes
 
410
             * close() then the FileDescriptor is also released.
 
411
             */
 
412
            runningFinalize.set(Boolean.TRUE);
 
413
            try {
 
414
                close();
 
415
            } finally {
 
416
                runningFinalize.set(Boolean.FALSE);
 
417
            }
 
418
        }
 
419
    }
 
420
}