1. /*
  2. * @(#)FileInputStream.java 1.60 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.io;
  8. import java.nio.channels.FileChannel;
  9. import sun.nio.ch.FileChannelImpl;
  10. /**
  11. * A <code>FileInputStream</code> obtains input bytes
  12. * from a file in a file system. What files
  13. * are available depends on the host environment.
  14. *
  15. * <p><code>FileInputStream</code> is meant for reading streams of raw bytes
  16. * such as image data. For reading streams of characters, consider using
  17. * <code>FileReader</code>.
  18. *
  19. * @author Arthur van Hoff
  20. * @version 1.60, 01/23/03
  21. * @see java.io.File
  22. * @see java.io.FileDescriptor
  23. * @see java.io.FileOutputStream
  24. * @since JDK1.0
  25. */
  26. public
  27. class FileInputStream extends InputStream
  28. {
  29. /* File Descriptor - handle to the open file */
  30. private FileDescriptor fd;
  31. private FileChannel channel = null;
  32. /**
  33. * Creates a <code>FileInputStream</code> by
  34. * opening a connection to an actual file,
  35. * the file named by the path name <code>name</code>
  36. * in the file system. A new <code>FileDescriptor</code>
  37. * object is created to represent this file
  38. * connection.
  39. * <p>
  40. * First, if there is a security
  41. * manager, its <code>checkRead</code> method
  42. * is called with the <code>name</code> argument
  43. * as its argument.
  44. * <p>
  45. * If the named file does not exist, is a directory rather than a regular
  46. * file, or for some other reason cannot be opened for reading then a
  47. * <code>FileNotFoundException</code> is thrown.
  48. *
  49. * @param name the system-dependent file name.
  50. * @exception FileNotFoundException if the file does not exist,
  51. * is a directory rather than a regular file,
  52. * or for some other reason cannot be opened for
  53. * reading.
  54. * @exception SecurityException if a security manager exists and its
  55. * <code>checkRead</code> method denies read access
  56. * to the file.
  57. * @see java.lang.SecurityManager#checkRead(java.lang.String)
  58. */
  59. public FileInputStream(String name) throws FileNotFoundException {
  60. this(name != null ? new File(name) : null);
  61. }
  62. /**
  63. * Creates a <code>FileInputStream</code> by
  64. * opening a connection to an actual file,
  65. * the file named by the <code>File</code>
  66. * object <code>file</code> in the file system.
  67. * A new <code>FileDescriptor</code> object
  68. * is created to represent this file connection.
  69. * <p>
  70. * First, if there is a security manager,
  71. * its <code>checkRead</code> method is called
  72. * with the path represented by the <code>file</code>
  73. * argument as its argument.
  74. * <p>
  75. * If the named file does not exist, is a directory rather than a regular
  76. * file, or for some other reason cannot be opened for reading then a
  77. * <code>FileNotFoundException</code> is thrown.
  78. *
  79. * @param file the file to be opened for reading.
  80. * @exception FileNotFoundException if the file does not exist,
  81. * is a directory rather than a regular file,
  82. * or for some other reason cannot be opened for
  83. * reading.
  84. * @exception SecurityException if a security manager exists and its
  85. * <code>checkRead</code> method denies read access to the file.
  86. * @see java.io.File#getPath()
  87. * @see java.lang.SecurityManager#checkRead(java.lang.String)
  88. */
  89. public FileInputStream(File file) throws FileNotFoundException {
  90. String name = (file != null ? file.getPath() : null);
  91. SecurityManager security = System.getSecurityManager();
  92. if (security != null) {
  93. security.checkRead(name);
  94. }
  95. if (name == null) {
  96. throw new NullPointerException();
  97. }
  98. fd = new FileDescriptor();
  99. open(name);
  100. }
  101. /**
  102. * Creates a <code>FileInputStream</code> by using the file descriptor
  103. * <code>fdObj</code>, which represents an existing connection to an
  104. * actual file in the file system.
  105. * <p>
  106. * If there is a security manager, its <code>checkRead</code> method is
  107. * called with the file descriptor <code>fdObj</code> as its argument to
  108. * see if it's ok to read the file descriptor. If read access is denied
  109. * to the file descriptor a <code>SecurityException</code> is thrown.
  110. * <p>
  111. * If <code>fdObj</code> is null then a <code>NullPointerException</code>
  112. * is thrown.
  113. *
  114. * @param fdObj the file descriptor to be opened for reading.
  115. * @throws SecurityException if a security manager exists and its
  116. * <code>checkRead</code> method denies read access to the
  117. * file descriptor.
  118. * @see SecurityManager#checkRead(java.io.FileDescriptor)
  119. */
  120. public FileInputStream(FileDescriptor fdObj) {
  121. SecurityManager security = System.getSecurityManager();
  122. if (fdObj == null) {
  123. throw new NullPointerException();
  124. }
  125. if (security != null) {
  126. security.checkRead(fdObj);
  127. }
  128. fd = fdObj;
  129. }
  130. /**
  131. * Opens the specified file for reading.
  132. * @param name the name of the file
  133. */
  134. private native void open(String name) throws FileNotFoundException;
  135. /**
  136. * Reads a byte of data from this input stream. This method blocks
  137. * if no input is yet available.
  138. *
  139. * @return the next byte of data, or <code>-1</code> if the end of the
  140. * file is reached.
  141. * @exception IOException if an I/O error occurs.
  142. */
  143. public native int read() throws IOException;
  144. /**
  145. * Reads a subarray as a sequence of bytes.
  146. * @param b the data to be written
  147. * @param off the start offset in the data
  148. * @param len the number of bytes that are written
  149. * @exception IOException If an I/O error has occurred.
  150. */
  151. private native int readBytes(byte b[], int off, int len) throws IOException;
  152. /**
  153. * Reads up to <code>b.length</code> bytes of data from this input
  154. * stream into an array of bytes. This method blocks until some input
  155. * is available.
  156. *
  157. * @param b the buffer into which the data is read.
  158. * @return the total number of bytes read into the buffer, or
  159. * <code>-1</code> if there is no more data because the end of
  160. * the file has been reached.
  161. * @exception IOException if an I/O error occurs.
  162. */
  163. public int read(byte b[]) throws IOException {
  164. return readBytes(b, 0, b.length);
  165. }
  166. /**
  167. * Reads up to <code>len</code> bytes of data from this input stream
  168. * into an array of bytes. This method blocks until some input is
  169. * available.
  170. *
  171. * @param b the buffer into which the data is read.
  172. * @param off the start offset of the data.
  173. * @param len the maximum number of bytes read.
  174. * @return the total number of bytes read into the buffer, or
  175. * <code>-1</code> if there is no more data because the end of
  176. * the file has been reached.
  177. * @exception IOException if an I/O error occurs.
  178. */
  179. public int read(byte b[], int off, int len) throws IOException {
  180. return readBytes(b, off, len);
  181. }
  182. /**
  183. * Skips over and discards <code>n</code> bytes of data from the
  184. * input stream. The <code>skip</code> method may, for a variety of
  185. * reasons, end up skipping over some smaller number of bytes,
  186. * possibly <code>0</code>. The actual number of bytes skipped is returned.
  187. *
  188. * @param n the number of bytes to be skipped.
  189. * @return the actual number of bytes skipped.
  190. * @exception IOException if an I/O error occurs.
  191. */
  192. public native long skip(long n) throws IOException;
  193. /**
  194. * Returns the number of bytes that can be read from this file input
  195. * stream without blocking.
  196. *
  197. * @return the number of bytes that can be read from this file input
  198. * stream without blocking.
  199. * @exception IOException if an I/O error occurs.
  200. */
  201. public native int available() throws IOException;
  202. /**
  203. * Closes this file input stream and releases any system resources
  204. * associated with the stream.
  205. *
  206. * <p> If this stream has an associated channel then the channel is closed
  207. * as well.
  208. *
  209. * @exception IOException if an I/O error occurs.
  210. *
  211. * @revised 1.4
  212. * @spec JSR-51
  213. */
  214. public void close() throws IOException {
  215. if (channel != null)
  216. channel.close();
  217. close0();
  218. }
  219. /**
  220. * Returns the <code>FileDescriptor</code>
  221. * object that represents the connection to
  222. * the actual file in the file system being
  223. * used by this <code>FileInputStream</code>.
  224. *
  225. * @return the file descriptor object associated with this stream.
  226. * @exception IOException if an I/O error occurs.
  227. * @see java.io.FileDescriptor
  228. */
  229. public final FileDescriptor getFD() throws IOException {
  230. if (fd != null) return fd;
  231. throw new IOException();
  232. }
  233. /**
  234. * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
  235. * object associated with this file input stream.
  236. *
  237. * <p> The initial {@link java.nio.channels.FileChannel#position()
  238. * </code>position<code>} of the returned channel will be equal to the
  239. * number of bytes read from the file so far. Reading bytes from this
  240. * stream will increment the channel's position. Changing the channel's
  241. * position, either explicitly or by reading, will change this stream's
  242. * file position.
  243. *
  244. * @return the file channel associated with this file input stream
  245. *
  246. * @since 1.4
  247. * @spec JSR-51
  248. */
  249. public FileChannel getChannel() {
  250. synchronized (this) {
  251. if (channel == null)
  252. channel = FileChannelImpl.open(fd, true, false, this);
  253. return channel;
  254. }
  255. }
  256. private static native void initIDs();
  257. private native void close0() throws IOException;
  258. static {
  259. initIDs();
  260. }
  261. /**
  262. * Ensures that the <code>close</code> method of this file input stream is
  263. * called when there are no more references to it.
  264. *
  265. * @exception IOException if an I/O error occurs.
  266. * @see java.io.FileInputStream#close()
  267. */
  268. protected void finalize() throws IOException {
  269. if (fd != null) {
  270. if (fd != fd.in) {
  271. close();
  272. }
  273. }
  274. }
  275. }