001: /*
002: * @(#)FileInputStream.java 1.60 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.io;
029:
030: /**
031: * A <code>FileInputStream</code> obtains input bytes
032: * from a file in a file system. What files
033: * are available depends on the host environment.
034: *
035: * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
036: * such as image data. For reading streams of characters, consider using
037: * <code>FileReader</code>.
038: *
039: * @version 1.45, 02/02/00
040: * @see java.io.File
041: * @see java.io.FileDescriptor
042: * @see java.io.FileOutputStream
043: * @since JDK1.0
044: */
045: public class FileInputStream extends InputStream {
046: /* File Descriptor - handle to the open file */
047: private FileDescriptor fd;
048:
049: /**
050: * Creates a <code>FileInputStream</code> by
051: * opening a connection to an actual file,
052: * the file named by the path name <code>name</code>
053: * in the file system. A new <code>FileDescriptor</code>
054: * object is created to represent this file
055: * connection.
056: * <p>
057: * First, if there is a security
058: * manager, its <code>checkRead</code> method
059: * is called with the <code>name</code> argument
060: * as its argument.
061: * <p>
062: * If the named file does not exist, is a directory rather than a regular
063: * file, or for some other reason cannot be opened for reading then a
064: * <code>FileNotFoundException</code> is thrown.
065: *
066: * @param name the system-dependent file name.
067: * @exception FileNotFoundException if the file does not exist,
068: * is a directory rather than a regular file,
069: * or for some other reason cannot be opened for
070: * reading.
071: * @exception SecurityException if a security manager exists and its
072: * <code>checkRead</code> method denies read access
073: * to the file.
074: * @see java.lang.SecurityManager#checkRead(java.lang.String)
075: */
076: public FileInputStream(String name) throws FileNotFoundException {
077: this (name != null ? new File(name) : null);
078: }
079:
080: /**
081: * Creates a <code>FileInputStream</code> by
082: * opening a connection to an actual file,
083: * the file named by the <code>File</code>
084: * object <code>file</code> in the file system.
085: * A new <code>FileDescriptor</code> object
086: * is created to represent this file connection.
087: * <p>
088: * First, if there is a security manager,
089: * its <code>checkRead</code> method is called
090: * with the path represented by the <code>file</code>
091: * argument as its argument.
092: * <p>
093: * If the named file does not exist, is a directory rather than a regular
094: * file, or for some other reason cannot be opened for reading then a
095: * <code>FileNotFoundException</code> is thrown.
096: *
097: * @param file the file to be opened for reading.
098: * @exception FileNotFoundException if the file does not exist,
099: * is a directory rather than a regular file,
100: * or for some other reason cannot be opened for
101: * reading.
102: * @exception SecurityException if a security manager exists and its
103: * <code>checkRead</code> method denies read access to the file.
104: * @see java.io.File#getPath()
105: * @see java.lang.SecurityManager#checkRead(java.lang.String)
106: */
107: public FileInputStream(File file) throws FileNotFoundException {
108: String name = (file != null ? file.getPath() : null);
109: SecurityManager security = System.getSecurityManager();
110: if (security != null) {
111: security.checkRead(name);
112: }
113: if (name == null) {
114: throw new NullPointerException();
115: }
116: fd = new FileDescriptor();
117: open(name);
118: }
119:
120: /**
121: * Creates a <code>FileInputStream</code> by using the file descriptor
122: * <code>fdObj</code>, which represents an existing connection to an
123: * actual file in the file system.
124: * <p>
125: * If there is a security manager, its <code>checkRead</code> method is
126: * called with the file descriptor <code>fdObj</code> as its argument to
127: * see if it's ok to read the file descriptor. If read access is denied
128: * to the file descriptor a <code>SecurityException</code> is thrown.
129: * <p>
130: * If <code>fdObj</code> is null then a <code>NullPointerException</code>
131: * is thrown.
132: *
133: * @param fdObj the file descriptor to be opened for reading.
134: * @throws SecurityException if a security manager exists and its
135: * <code>checkRead</code> method denies read access to the
136: * file descriptor.
137: * @see SecurityManager#checkRead(java.io.FileDescriptor)
138: */
139: public FileInputStream(FileDescriptor fdObj) {
140: SecurityManager security = System.getSecurityManager();
141: if (fdObj == null) {
142: throw new NullPointerException();
143: }
144: if (security != null) {
145: security.checkRead(fdObj);
146: }
147: fd = fdObj;
148: }
149:
150: /**
151: * Opens the specified file for reading.
152: * @param name the name of the file
153: */
154: private native void open(String name) throws FileNotFoundException;
155:
156: /**
157: * Reads a byte of data from this input stream. This method blocks
158: * if no input is yet available.
159: *
160: * @return the next byte of data, or <code>-1</code> if the end of the
161: * file is reached.
162: * @exception IOException if an I/O error occurs.
163: */
164: public native int read() throws IOException;
165:
166: /**
167: * Reads a subarray as a sequence of bytes.
168: * @param b the data to be written
169: * @param off the start offset in the data
170: * @param len the number of bytes that are written
171: * @exception IOException If an I/O error has occurred.
172: */
173: private native int readBytes(byte b[], int off, int len)
174: throws IOException;
175:
176: /**
177: * Reads up to <code>b.length</code> bytes of data from this input
178: * stream into an array of bytes. This method blocks until some input
179: * is available.
180: *
181: * @param b the buffer into which the data is read.
182: * @return the total number of bytes read into the buffer, or
183: * <code>-1</code> if there is no more data because the end of
184: * the file has been reached.
185: * @exception IOException if an I/O error occurs.
186: */
187: public int read(byte b[]) throws IOException {
188: return readBytes(b, 0, b.length);
189: }
190:
191: /**
192: * Reads up to <code>len</code> bytes of data from this input stream
193: * into an array of bytes. This method blocks until some input is
194: * available.
195: *
196: * @param b the buffer into which the data is read.
197: * @param off the start offset of the data.
198: * @param len the maximum number of bytes read.
199: * @return the total number of bytes read into the buffer, or
200: * <code>-1</code> if there is no more data because the end of
201: * the file has been reached.
202: * @exception IOException if an I/O error occurs.
203: */
204: public int read(byte b[], int off, int len) throws IOException {
205: return readBytes(b, off, len);
206: }
207:
208: /**
209: * Skips over and discards <code>n</code> bytes of data from the
210: * input stream. The <code>skip</code> method may, for a variety of
211: * reasons, end up skipping over some smaller number of bytes,
212: * possibly <code>0</code>. The actual number of bytes skipped is returned.
213: *
214: * @param n the number of bytes to be skipped.
215: * @return the actual number of bytes skipped.
216: * @exception IOException if an I/O error occurs.
217: */
218: public native long skip(long n) throws IOException;
219:
220: /**
221: * Returns the number of bytes that can be read from this file input
222: * stream without blocking.
223: *
224: * @return the number of bytes that can be read from this file input
225: * stream without blocking.
226: * @exception IOException if an I/O error occurs.
227: */
228: public native int available() throws IOException;
229:
230: /**
231: * Closes this file input stream and releases any system resources
232: * associated with the stream.
233: *
234: * <p> If this stream has an associated channel then the channel is closed
235: * as well.
236: *
237: * @exception IOException if an I/O error occurs.
238: *
239: * @revised 1.4
240: * @spec JSR-51
241: */
242: public void close() throws IOException {
243: close0();
244: }
245:
246: /**
247: * Returns the <code>FileDescriptor</code>
248: * object that represents the connection to
249: * the actual file in the file system being
250: * used by this <code>FileInputStream</code>.
251: *
252: * @return the file descriptor object associated with this stream.
253: * @exception IOException if an I/O error occurs.
254: * @see java.io.FileDescriptor
255: */
256: public final FileDescriptor getFD() throws IOException {
257: if (fd != null)
258: return fd;
259: throw new IOException();
260: }
261:
262: /**
263: * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
264: * object associated with this file input stream.
265: *
266: * <p> The initial {@link java.nio.channels.FileChannel#position()
267: * </code>position<code>} of the returned channel will be equal to the
268: * number of bytes read from the file so far. Reading bytes from this
269: * stream will increment the channel's position. Changing the channel's
270: * position, either explicitly or by reading, will change this stream's
271: * file position.
272: *
273: * @return the file channel associated with this file input stream
274: *
275: * @since 1.4
276: * @spec JSR-51
277: */
278: /* Comment out due to no NIO in CDC
279: public FileChannel getChannel() {
280: synchronized (this) {
281: if (channel == null)
282: channel = FileChannelImpl.open(fd, true, false, this);
283: return channel;
284: }
285: }
286: */
287:
288: private static native void initIDs();
289:
290: private native void close0() throws IOException;
291:
292: static {
293: initIDs();
294: }
295:
296: /**
297: * Ensures that the <code>close</code> method of this file input stream is
298: * called when there are no more references to it.
299: *
300: * @exception IOException if an I/O error occurs.
301: * @see java.io.FileInputStream#close()
302: */
303: protected void finalize() throws IOException {
304: if (fd != null) {
305: if (fd != fd.in) {
306: close();
307: }
308: }
309: }
310: }
|