1. /*
  2. * @(#)RandomAccessFile.java 1.78 04/05/13
  3. *
  4. * Copyright 2004 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. * Instances of this class support both reading and writing to a
  12. * random access file. A random access file behaves like a large
  13. * array of bytes stored in the file system. There is a kind of cursor,
  14. * or index into the implied array, called the <em>file pointer</em>
  15. * input operations read bytes starting at the file pointer and advance
  16. * the file pointer past the bytes read. If the random access file is
  17. * created in read/write mode, then output operations are also available;
  18. * output operations write bytes starting at the file pointer and advance
  19. * the file pointer past the bytes written. Output operations that write
  20. * past the current end of the implied array cause the array to be
  21. * extended. The file pointer can be read by the
  22. * <code>getFilePointer</code> method and set by the <code>seek</code>
  23. * method.
  24. * <p>
  25. * It is generally true of all the reading routines in this class that
  26. * if end-of-file is reached before the desired number of bytes has been
  27. * read, an <code>EOFException</code> (which is a kind of
  28. * <code>IOException</code>) is thrown. If any byte cannot be read for
  29. * any reason other than end-of-file, an <code>IOException</code> other
  30. * than <code>EOFException</code> is thrown. In particular, an
  31. * <code>IOException</code> may be thrown if the stream has been closed.
  32. *
  33. * @author unascribed
  34. * @version 1.78, 05/13/04
  35. * @since JDK1.0
  36. */
  37. public class RandomAccessFile implements DataOutput, DataInput, Closeable {
  38. private FileDescriptor fd;
  39. private FileChannel channel = null;
  40. private boolean rw;
  41. private static final int O_RDONLY = 1;
  42. private static final int O_RDWR = 2;
  43. private static final int O_SYNC = 4;
  44. private static final int O_DSYNC = 8;
  45. /**
  46. * Creates a random access file stream to read from, and optionally
  47. * to write to, a file with the specified name. A new
  48. * {@link FileDescriptor} object is created to represent the
  49. * connection to the file.
  50. *
  51. * <p> The <tt>mode</tt> argument specifies the access mode with which the
  52. * file is to be opened. The permitted values and their meanings are as
  53. * specified for the <a
  54. * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
  55. *
  56. * <p>
  57. * If there is a security manager, its <code>checkRead</code> method
  58. * is called with the <code>name</code> argument
  59. * as its argument to see if read access to the file is allowed.
  60. * If the mode allows writing, the security manager's
  61. * <code>checkWrite</code> method
  62. * is also called with the <code>name</code> argument
  63. * as its argument to see if write access to the file is allowed.
  64. *
  65. * @param name the system-dependent filename
  66. * @param mode the access <a href="#mode">mode</a>
  67. * @exception IllegalArgumentException if the mode argument is not equal
  68. * to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
  69. * <tt>"rwd"</tt>
  70. * @exception FileNotFoundException
  71. * if the mode is <tt>"r"</tt> but the given string does not
  72. * denote an existing regular file, or if the mode begins with
  73. * <tt>"rw"</tt> but the given string does not denote an
  74. * existing, writable regular file and a new regular file of
  75. * that name cannot be created, or if some other error occurs
  76. * while opening or creating the file
  77. * @exception SecurityException if a security manager exists and its
  78. * <code>checkRead</code> method denies read access to the file
  79. * or the mode is "rw" and the security manager's
  80. * <code>checkWrite</code> method denies write access to the file
  81. * @see java.lang.SecurityException
  82. * @see java.lang.SecurityManager#checkRead(java.lang.String)
  83. * @see java.lang.SecurityManager#checkWrite(java.lang.String)
  84. * @revised 1.4
  85. * @spec JSR-51
  86. */
  87. public RandomAccessFile(String name, String mode)
  88. throws FileNotFoundException
  89. {
  90. this(name != null ? new File(name) : null, mode);
  91. }
  92. /**
  93. * Creates a random access file stream to read from, and optionally to
  94. * write to, the file specified by the {@link File} argument. A new {@link
  95. * FileDescriptor} object is created to represent this file connection.
  96. *
  97. * <a name="mode"><p> The <tt>mode</tt> argument specifies the access mode
  98. * in which the file is to be opened. The permitted values and their
  99. * meanings are:
  100. *
  101. * <blockquote><table summary="Access mode permitted values and meanings">
  102. * <tr><th><p align="left">Value</p></th><th><p align="left">Meaning</p></th></tr>
  103. * <tr><td valign="top"><tt>"r"</tt></td>
  104. * <td> Open for reading only. Invoking any of the <tt>write</tt>
  105. * methods of the resulting object will cause an {@link
  106. * java.io.IOException} to be thrown. </td></tr>
  107. * <tr><td valign="top"><tt>"rw"</tt></td>
  108. * <td> Open for reading and writing. If the file does not already
  109. * exist then an attempt will be made to create it. </td></tr>
  110. * <tr><td valign="top"><tt>"rws"</tt></td>
  111. * <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
  112. * require that every update to the file's content or metadata be
  113. * written synchronously to the underlying storage device. </td></tr>
  114. * <tr><td valign="top"><tt>"rwd"  </tt></td>
  115. * <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
  116. * require that every update to the file's content be written
  117. * synchronously to the underlying storage device. </td></tr>
  118. * </table></blockquote>
  119. *
  120. * The <tt>"rws"</tt> and <tt>"rwd"</tt> modes work much like the {@link
  121. * java.nio.channels.FileChannel#force(boolean) force(boolean)} method of
  122. * the {@link java.nio.channels.FileChannel} class, passing arguments of
  123. * <tt>true</tt> and <tt>false</tt>, respectively, except that they always
  124. * apply to every I/O operation and are therefore often more efficient. If
  125. * the file resides on a local storage device then when an invocation of a
  126. * method of this class returns it is guaranteed that all changes made to
  127. * the file by that invocation will have been written to that device. This
  128. * is useful for ensuring that critical information is not lost in the
  129. * event of a system crash. If the file does not reside on a local device
  130. * then no such guarantee is made.
  131. *
  132. * <p> The <tt>"rwd"</tt> mode can be used to reduce the number of I/O
  133. * operations performed. Using <tt>"rwd"</tt> only requires updates to the
  134. * file's content to be written to storage; using <tt>"rws"</tt> requires
  135. * updates to both the file's content and its metadata to be written, which
  136. * generally requires at least one more low-level I/O operation.
  137. *
  138. * <p> If there is a security manager, its <code>checkRead</code> method is
  139. * called with the pathname of the <code>file</code> argument as its
  140. * argument to see if read access to the file is allowed. If the mode
  141. * allows writing, the security manager's <code>checkWrite</code> method is
  142. * also called with the path argument to see if write access to the file is
  143. * allowed.
  144. *
  145. * @param file the file object
  146. * @param mode the access mode, as described
  147. * <a href="#mode">above</a>
  148. * @exception IllegalArgumentException if the mode argument is not equal
  149. * to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
  150. * <tt>"rwd"</tt>
  151. * @exception FileNotFoundException
  152. * if the mode is <tt>"r"</tt> but the given file object does
  153. * not denote an existing regular file, or if the mode begins
  154. * with <tt>"rw"</tt> but the given file object does not denote
  155. * an existing, writable regular file and a new regular file of
  156. * that name cannot be created, or if some other error occurs
  157. * while opening or creating the file
  158. * @exception SecurityException if a security manager exists and its
  159. * <code>checkRead</code> method denies read access to the file
  160. * or the mode is "rw" and the security manager's
  161. * <code>checkWrite</code> method denies write access to the file
  162. * @see java.lang.SecurityManager#checkRead(java.lang.String)
  163. * @see java.lang.SecurityManager#checkWrite(java.lang.String)
  164. * @see java.nio.channels.FileChannel#force(boolean)
  165. * @revised 1.4
  166. * @spec JSR-51
  167. */
  168. public RandomAccessFile(File file, String mode)
  169. throws FileNotFoundException
  170. {
  171. String name = (file != null ? file.getPath() : null);
  172. int imode = -1;
  173. if (mode.equals("r"))
  174. imode = O_RDONLY;
  175. else if (mode.startsWith("rw")) {
  176. imode = O_RDWR;
  177. rw = true;
  178. if (mode.length() > 2) {
  179. if (mode.equals("rws"))
  180. imode |= O_SYNC;
  181. else if (mode.equals("rwd"))
  182. imode |= O_DSYNC;
  183. else
  184. imode = -1;
  185. }
  186. }
  187. if (imode < 0)
  188. throw new IllegalArgumentException("Illegal mode \"" + mode
  189. + "\" must be one of "
  190. + "\"r\", \"rw\", \"rws\","
  191. + " or \"rwd\"");
  192. SecurityManager security = System.getSecurityManager();
  193. if (security != null) {
  194. security.checkRead(name);
  195. if (rw) {
  196. security.checkWrite(name);
  197. }
  198. }
  199. if (name == null) {
  200. throw new NullPointerException();
  201. }
  202. fd = new FileDescriptor();
  203. open(name, imode);
  204. }
  205. /**
  206. * Returns the opaque file descriptor object associated with this
  207. * stream. </p>
  208. *
  209. * @return the file descriptor object associated with this stream.
  210. * @exception IOException if an I/O error occurs.
  211. * @see java.io.FileDescriptor
  212. */
  213. public final FileDescriptor getFD() throws IOException {
  214. if (fd != null) return fd;
  215. throw new IOException();
  216. }
  217. /**
  218. * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
  219. * object associated with this file.
  220. *
  221. * <p> The {@link java.nio.channels.FileChannel#position()
  222. * </code>position<code>} of the returned channel will always be equal to
  223. * this object's file-pointer offset as returned by the {@link
  224. * #getFilePointer getFilePointer} method. Changing this object's
  225. * file-pointer offset, whether explicitly or by reading or writing bytes,
  226. * will change the position of the channel, and vice versa. Changing the
  227. * file's length via this object will change the length seen via the file
  228. * channel, and vice versa.
  229. *
  230. * @return the file channel associated with this file
  231. *
  232. * @since 1.4
  233. * @spec JSR-51
  234. */
  235. public final FileChannel getChannel() {
  236. synchronized (this) {
  237. if (channel == null)
  238. channel = FileChannelImpl.open(fd, true, rw, this);
  239. return channel;
  240. }
  241. }
  242. /**
  243. * Opens a file and returns the file descriptor. The file is
  244. * opened in read-write mode if the O_RDWR bit in <code>mode</code>
  245. * is true, else the file is opened as read-only.
  246. * If the <code>name</code> refers to a directory, an IOException
  247. * is thrown.
  248. *
  249. * @param name the name of the file
  250. * @param mode the mode flags, a combination of the O_ constants
  251. * defined above
  252. */
  253. private native void open(String name, int mode)
  254. throws FileNotFoundException;
  255. // 'Read' primitives
  256. /**
  257. * Reads a byte of data from this file. The byte is returned as an
  258. * integer in the range 0 to 255 (<code>0x00-0x0ff</code>). This
  259. * method blocks if no input is yet available.
  260. * <p>
  261. * Although <code>RandomAccessFile</code> is not a subclass of
  262. * <code>InputStream</code>, this method behaves in exactly the same
  263. * way as the {@link InputStream#read()} method of
  264. * <code>InputStream</code>.
  265. *
  266. * @return the next byte of data, or <code>-1</code> if the end of the
  267. * file has been reached.
  268. * @exception IOException if an I/O error occurs. Not thrown if
  269. * end-of-file has been reached.
  270. */
  271. public native int read() throws IOException;
  272. /**
  273. * Reads a sub array as a sequence of bytes.
  274. * @param b the buffer into which the data is read.
  275. * @param off the start offset of the data.
  276. * @param len the number of bytes to read.
  277. * @exception IOException If an I/O error has occurred.
  278. */
  279. private native int readBytes(byte b[], int off, int len) throws IOException;
  280. /**
  281. * Reads up to <code>len</code> bytes of data from this file into an
  282. * array of bytes. This method blocks until at least one byte of input
  283. * is available.
  284. * <p>
  285. * Although <code>RandomAccessFile</code> is not a subclass of
  286. * <code>InputStream</code>, this method behaves in exactly the
  287. * same way as the {@link InputStream#read(byte[], int, int)} method of
  288. * <code>InputStream</code>.
  289. *
  290. * @param b the buffer into which the data is read.
  291. * @param off the start offset of the data.
  292. * @param len the maximum number of bytes read.
  293. * @return the total number of bytes read into the buffer, or
  294. * <code>-1</code> if there is no more data because the end of
  295. * the file has been reached.
  296. * @exception IOException if an I/O error occurs.
  297. */
  298. public int read(byte b[], int off, int len) throws IOException {
  299. return readBytes(b, off, len);
  300. }
  301. /**
  302. * Reads up to <code>b.length</code> bytes of data from this file
  303. * into an array of bytes. This method blocks until at least one byte
  304. * of input is available.
  305. * <p>
  306. * Although <code>RandomAccessFile</code> is not a subclass of
  307. * <code>InputStream</code>, this method behaves in exactly the
  308. * same way as the {@link InputStream#read(byte[])} method of
  309. * <code>InputStream</code>.
  310. *
  311. * @param b the buffer into which the data is read.
  312. * @return the total number of bytes read into the buffer, or
  313. * <code>-1</code> if there is no more data because the end of
  314. * this file has been reached.
  315. * @exception IOException if an I/O error occurs.
  316. */
  317. public int read(byte b[]) throws IOException {
  318. return readBytes(b, 0, b.length);
  319. }
  320. /**
  321. * Reads <code>b.length</code> bytes from this file into the byte
  322. * array, starting at the current file pointer. This method reads
  323. * repeatedly from the file until the requested number of bytes are
  324. * read. This method blocks until the requested number of bytes are
  325. * read, the end of the stream is detected, or an exception is thrown.
  326. *
  327. * @param b the buffer into which the data is read.
  328. * @exception EOFException if this file reaches the end before reading
  329. * all the bytes.
  330. * @exception IOException if an I/O error occurs.
  331. */
  332. public final void readFully(byte b[]) throws IOException {
  333. readFully(b, 0, b.length);
  334. }
  335. /**
  336. * Reads exactly <code>len</code> bytes from this file into the byte
  337. * array, starting at the current file pointer. This method reads
  338. * repeatedly from the file until the requested number of bytes are
  339. * read. This method blocks until the requested number of bytes are
  340. * read, the end of the stream is detected, or an exception is thrown.
  341. *
  342. * @param b the buffer into which the data is read.
  343. * @param off the start offset of the data.
  344. * @param len the number of bytes to read.
  345. * @exception EOFException if this file reaches the end before reading
  346. * all the bytes.
  347. * @exception IOException if an I/O error occurs.
  348. */
  349. public final void readFully(byte b[], int off, int len) throws IOException {
  350. int n = 0;
  351. do {
  352. int count = this.read(b, off + n, len - n);
  353. if (count < 0)
  354. throw new EOFException();
  355. n += count;
  356. } while (n < len);
  357. }
  358. /**
  359. * Attempts to skip over <code>n</code> bytes of input discarding the
  360. * skipped bytes.
  361. * <p>
  362. *
  363. * This method may skip over some smaller number of bytes, possibly zero.
  364. * This may result from any of a number of conditions; reaching end of
  365. * file before <code>n</code> bytes have been skipped is only one
  366. * possibility. This method never throws an <code>EOFException</code>.
  367. * The actual number of bytes skipped is returned. If <code>n</code>
  368. * is negative, no bytes are skipped.
  369. *
  370. * @param n the number of bytes to be skipped.
  371. * @return the actual number of bytes skipped.
  372. * @exception IOException if an I/O error occurs.
  373. */
  374. public int skipBytes(int n) throws IOException {
  375. long pos;
  376. long len;
  377. long newpos;
  378. if (n <= 0) {
  379. return 0;
  380. }
  381. pos = getFilePointer();
  382. len = length();
  383. newpos = pos + n;
  384. if (newpos > len) {
  385. newpos = len;
  386. }
  387. seek(newpos);
  388. /* return the actual number of bytes skipped */
  389. return (int) (newpos - pos);
  390. }
  391. // 'Write' primitives
  392. /**
  393. * Writes the specified byte to this file. The write starts at
  394. * the current file pointer.
  395. *
  396. * @param b the <code>byte</code> to be written.
  397. * @exception IOException if an I/O error occurs.
  398. */
  399. public native void write(int b) throws IOException;
  400. /**
  401. * Writes a sub array as a sequence of bytes.
  402. * @param b the data to be written
  403. * @param off the start offset in the data
  404. * @param len the number of bytes that are written
  405. * @exception IOException If an I/O error has occurred.
  406. */
  407. private native void writeBytes(byte b[], int off, int len) throws IOException;
  408. /**
  409. * Writes <code>b.length</code> bytes from the specified byte array
  410. * to this file, starting at the current file pointer.
  411. *
  412. * @param b the data.
  413. * @exception IOException if an I/O error occurs.
  414. */
  415. public void write(byte b[]) throws IOException {
  416. writeBytes(b, 0, b.length);
  417. }
  418. /**
  419. * Writes <code>len</code> bytes from the specified byte array
  420. * starting at offset <code>off</code> to this file.
  421. *
  422. * @param b the data.
  423. * @param off the start offset in the data.
  424. * @param len the number of bytes to write.
  425. * @exception IOException if an I/O error occurs.
  426. */
  427. public void write(byte b[], int off, int len) throws IOException {
  428. writeBytes(b, off, len);
  429. }
  430. // 'Random access' stuff
  431. /**
  432. * Returns the current offset in this file.
  433. *
  434. * @return the offset from the beginning of the file, in bytes,
  435. * at which the next read or write occurs.
  436. * @exception IOException if an I/O error occurs.
  437. */
  438. public native long getFilePointer() throws IOException;
  439. /**
  440. * Sets the file-pointer offset, measured from the beginning of this
  441. * file, at which the next read or write occurs. The offset may be
  442. * set beyond the end of the file. Setting the offset beyond the end
  443. * of the file does not change the file length. The file length will
  444. * change only by writing after the offset has been set beyond the end
  445. * of the file.
  446. *
  447. * @param pos the offset position, measured in bytes from the
  448. * beginning of the file, at which to set the file
  449. * pointer.
  450. * @exception IOException if <code>pos</code> is less than
  451. * <code>0</code> or if an I/O error occurs.
  452. */
  453. public native void seek(long pos) throws IOException;
  454. /**
  455. * Returns the length of this file.
  456. *
  457. * @return the length of this file, measured in bytes.
  458. * @exception IOException if an I/O error occurs.
  459. */
  460. public native long length() throws IOException;
  461. /**
  462. * Sets the length of this file.
  463. *
  464. * <p> If the present length of the file as returned by the
  465. * <code>length</code> method is greater than the <code>newLength</code>
  466. * argument then the file will be truncated. In this case, if the file
  467. * offset as returned by the <code>getFilePointer</code> method is greater
  468. * than <code>newLength</code> then after this method returns the offset
  469. * will be equal to <code>newLength</code>.
  470. *
  471. * <p> If the present length of the file as returned by the
  472. * <code>length</code> method is smaller than the <code>newLength</code>
  473. * argument then the file will be extended. In this case, the contents of
  474. * the extended portion of the file are not defined.
  475. *
  476. * @param newLength The desired length of the file
  477. * @exception IOException If an I/O error occurs
  478. * @since 1.2
  479. */
  480. public native void setLength(long newLength) throws IOException;
  481. /**
  482. * Closes this random access file stream and releases any system
  483. * resources associated with the stream. A closed random access
  484. * file cannot perform input or output operations and cannot be
  485. * reopened.
  486. *
  487. * <p> If this file has an associated channel then the channel is closed
  488. * as well.
  489. *
  490. * @exception IOException if an I/O error occurs.
  491. *
  492. * @revised 1.4
  493. * @spec JSR-51
  494. */
  495. public void close() throws IOException {
  496. if (channel != null)
  497. channel.close();
  498. close0();
  499. }
  500. //
  501. // Some "reading/writing Java data types" methods stolen from
  502. // DataInputStream and DataOutputStream.
  503. //
  504. /**
  505. * Reads a <code>boolean</code> from this file. This method reads a
  506. * single byte from the file, starting at the current file pointer.
  507. * A value of <code>0</code> represents
  508. * <code>false</code>. Any other value represents <code>true</code>.
  509. * This method blocks until the byte is read, the end of the stream
  510. * is detected, or an exception is thrown.
  511. *
  512. * @return the <code>boolean</code> value read.
  513. * @exception EOFException if this file has reached the end.
  514. * @exception IOException if an I/O error occurs.
  515. */
  516. public final boolean readBoolean() throws IOException {
  517. int ch = this.read();
  518. if (ch < 0)
  519. throw new EOFException();
  520. return (ch != 0);
  521. }
  522. /**
  523. * Reads a signed eight-bit value from this file. This method reads a
  524. * byte from the file, starting from the current file pointer.
  525. * If the byte read is <code>b</code>, where
  526. * <code>0 <= b <= 255</code>,
  527. * then the result is:
  528. * <blockquote><pre>
  529. * (byte)(b)
  530. * </pre></blockquote>
  531. * <p>
  532. * This method blocks until the byte is read, the end of the stream
  533. * is detected, or an exception is thrown.
  534. *
  535. * @return the next byte of this file as a signed eight-bit
  536. * <code>byte</code>.
  537. * @exception EOFException if this file has reached the end.
  538. * @exception IOException if an I/O error occurs.
  539. */
  540. public final byte readByte() throws IOException {
  541. int ch = this.read();
  542. if (ch < 0)
  543. throw new EOFException();
  544. return (byte)(ch);
  545. }
  546. /**
  547. * Reads an unsigned eight-bit number from this file. This method reads
  548. * a byte from this file, starting at the current file pointer,
  549. * and returns that byte.
  550. * <p>
  551. * This method blocks until the byte is read, the end of the stream
  552. * is detected, or an exception is thrown.
  553. *
  554. * @return the next byte of this file, interpreted as an unsigned
  555. * eight-bit number.
  556. * @exception EOFException if this file has reached the end.
  557. * @exception IOException if an I/O error occurs.
  558. */
  559. public final int readUnsignedByte() throws IOException {
  560. int ch = this.read();
  561. if (ch < 0)
  562. throw new EOFException();
  563. return ch;
  564. }
  565. /**
  566. * Reads a signed 16-bit number from this file. The method reads two
  567. * bytes from this file, starting at the current file pointer.
  568. * If the two bytes read, in order, are
  569. * <code>b1</code> and <code>b2</code>, where each of the two values is
  570. * between <code>0</code> and <code>255</code>, inclusive, then the
  571. * result is equal to:
  572. * <blockquote><pre>
  573. * (short)((b1 << 8) | b2)
  574. * </pre></blockquote>
  575. * <p>
  576. * This method blocks until the two bytes are read, the end of the
  577. * stream is detected, or an exception is thrown.
  578. *
  579. * @return the next two bytes of this file, interpreted as a signed
  580. * 16-bit number.
  581. * @exception EOFException if this file reaches the end before reading
  582. * two bytes.
  583. * @exception IOException if an I/O error occurs.
  584. */
  585. public final short readShort() throws IOException {
  586. int ch1 = this.read();
  587. int ch2 = this.read();
  588. if ((ch1 | ch2) < 0)
  589. throw new EOFException();
  590. return (short)((ch1 << 8) + (ch2 << 0));
  591. }
  592. /**
  593. * Reads an unsigned 16-bit number from this file. This method reads
  594. * two bytes from the file, starting at the current file pointer.
  595. * If the bytes read, in order, are
  596. * <code>b1</code> and <code>b2</code>, where
  597. * <code>0 <= b1, b2 <= 255</code>,
  598. * then the result is equal to:
  599. * <blockquote><pre>
  600. * (b1 << 8) | b2
  601. * </pre></blockquote>
  602. * <p>
  603. * This method blocks until the two bytes are read, the end of the
  604. * stream is detected, or an exception is thrown.
  605. *
  606. * @return the next two bytes of this file, interpreted as an unsigned
  607. * 16-bit integer.
  608. * @exception EOFException if this file reaches the end before reading
  609. * two bytes.
  610. * @exception IOException if an I/O error occurs.
  611. */
  612. public final int readUnsignedShort() throws IOException {
  613. int ch1 = this.read();
  614. int ch2 = this.read();
  615. if ((ch1 | ch2) < 0)
  616. throw new EOFException();
  617. return (ch1 << 8) + (ch2 << 0);
  618. }
  619. /**
  620. * Reads a Unicode character from this file. This method reads two
  621. * bytes from the file, starting at the current file pointer.
  622. * If the bytes read, in order, are
  623. * <code>b1</code> and <code>b2</code>, where
  624. * <code>0 <= b1, b2 <= 255</code>,
  625. * then the result is equal to:
  626. * <blockquote><pre>
  627. * (char)((b1 << 8) | b2)
  628. * </pre></blockquote>
  629. * <p>
  630. * This method blocks until the two bytes are read, the end of the
  631. * stream is detected, or an exception is thrown.
  632. *
  633. * @return the next two bytes of this file as a Unicode character.
  634. * @exception EOFException if this file reaches the end before reading
  635. * two bytes.
  636. * @exception IOException if an I/O error occurs.
  637. */
  638. public final char readChar() throws IOException {
  639. int ch1 = this.read();
  640. int ch2 = this.read();
  641. if ((ch1 | ch2) < 0)
  642. throw new EOFException();
  643. return (char)((ch1 << 8) + (ch2 << 0));
  644. }
  645. /**
  646. * Reads a signed 32-bit integer from this file. This method reads 4
  647. * bytes from the file, starting at the current file pointer.
  648. * If the bytes read, in order, are <code>b1</code>,
  649. * <code>b2</code>, <code>b3</code>, and <code>b4</code>, where
  650. * <code>0 <= b1, b2, b3, b4 <= 255</code>,
  651. * then the result is equal to:
  652. * <blockquote><pre>
  653. * (b1 << 24) | (b2 << 16) + (b3 << 8) + b4
  654. * </pre></blockquote>
  655. * <p>
  656. * This method blocks until the four bytes are read, the end of the
  657. * stream is detected, or an exception is thrown.
  658. *
  659. * @return the next four bytes of this file, interpreted as an
  660. * <code>int</code>.
  661. * @exception EOFException if this file reaches the end before reading
  662. * four bytes.
  663. * @exception IOException if an I/O error occurs.
  664. */
  665. public final int readInt() throws IOException {
  666. int ch1 = this.read();
  667. int ch2 = this.read();
  668. int ch3 = this.read();
  669. int ch4 = this.read();
  670. if ((ch1 | ch2 | ch3 | ch4) < 0)
  671. throw new EOFException();
  672. return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
  673. }
  674. /**
  675. * Reads a signed 64-bit integer from this file. This method reads eight
  676. * bytes from the file, starting at the current file pointer.
  677. * If the bytes read, in order, are
  678. * <code>b1</code>, <code>b2</code>, <code>b3</code>,
  679. * <code>b4</code>, <code>b5</code>, <code>b6</code>,
  680. * <code>b7</code>, and <code>b8,</code> where:
  681. * <blockquote><pre>
  682. * 0 <= b1, b2, b3, b4, b5, b6, b7, b8 <=255,
  683. * </pre></blockquote>
  684. * <p>
  685. * then the result is equal to:
  686. * <p><blockquote><pre>
  687. * ((long)b1 << 56) + ((long)b2 << 48)
  688. * + ((long)b3 << 40) + ((long)b4 << 32)
  689. * + ((long)b5 << 24) + ((long)b6 << 16)
  690. * + ((long)b7 << 8) + b8
  691. * </pre></blockquote>
  692. * <p>
  693. * This method blocks until the eight bytes are read, the end of the
  694. * stream is detected, or an exception is thrown.
  695. *
  696. * @return the next eight bytes of this file, interpreted as a
  697. * <code>long</code>.
  698. * @exception EOFException if this file reaches the end before reading
  699. * eight bytes.
  700. * @exception IOException if an I/O error occurs.
  701. */
  702. public final long readLong() throws IOException {
  703. return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
  704. }
  705. /**
  706. * Reads a <code>float</code> from this file. This method reads an
  707. * <code>int</code> value, starting at the current file pointer,
  708. * as if by the <code>readInt</code> method
  709. * and then converts that <code>int</code> to a <code>float</code>
  710. * using the <code>intBitsToFloat</code> method in class
  711. * <code>Float</code>.
  712. * <p>
  713. * This method blocks until the four bytes are read, the end of the
  714. * stream is detected, or an exception is thrown.
  715. *
  716. * @return the next four bytes of this file, interpreted as a
  717. * <code>float</code>.
  718. * @exception EOFException if this file reaches the end before reading
  719. * four bytes.
  720. * @exception IOException if an I/O error occurs.
  721. * @see java.io.RandomAccessFile#readInt()
  722. * @see java.lang.Float#intBitsToFloat(int)
  723. */
  724. public final float readFloat() throws IOException {
  725. return Float.intBitsToFloat(readInt());
  726. }
  727. /**
  728. * Reads a <code>double</code> from this file. This method reads a
  729. * <code>long</code> value, starting at the current file pointer,
  730. * as if by the <code>readLong</code> method
  731. * and then converts that <code>long</code> to a <code>double</code>
  732. * using the <code>longBitsToDouble</code> method in
  733. * class <code>Double</code>.
  734. * <p>
  735. * This method blocks until the eight bytes are read, the end of the
  736. * stream is detected, or an exception is thrown.
  737. *
  738. * @return the next eight bytes of this file, interpreted as a
  739. * <code>double</code>.
  740. * @exception EOFException if this file reaches the end before reading
  741. * eight bytes.
  742. * @exception IOException if an I/O error occurs.
  743. * @see java.io.RandomAccessFile#readLong()
  744. * @see java.lang.Double#longBitsToDouble(long)
  745. */
  746. public final double readDouble() throws IOException {
  747. return Double.longBitsToDouble(readLong());
  748. }
  749. /**
  750. * Reads the next line of text from this file. This method successively
  751. * reads bytes from the file, starting at the current file pointer,
  752. * until it reaches a line terminator or the end
  753. * of the file. Each byte is converted into a character by taking the
  754. * byte's value for the lower eight bits of the character and setting the
  755. * high eight bits of the character to zero. This method does not,
  756. * therefore, support the full Unicode character set.
  757. *
  758. * <p> A line of text is terminated by a carriage-return character
  759. * (<code>'\r'</code>), a newline character (<code>'\n'</code>), a
  760. * carriage-return character immediately followed by a newline character,
  761. * or the end of the file. Line-terminating characters are discarded and
  762. * are not included as part of the string returned.
  763. *
  764. * <p> This method blocks until a newline character is read, a carriage
  765. * return and the byte following it are read (to see if it is a newline),
  766. * the end of the file is reached, or an exception is thrown.
  767. *
  768. * @return the next line of text from this file, or null if end
  769. * of file is encountered before even one byte is read.
  770. * @exception IOException if an I/O error occurs.
  771. */
  772. public final String readLine() throws IOException {
  773. StringBuffer input = new StringBuffer();
  774. int c = -1;
  775. boolean eol = false;
  776. while (!eol) {
  777. switch (c = read()) {
  778. case -1:
  779. case '\n':
  780. eol = true;
  781. break;
  782. case '\r':
  783. eol = true;
  784. long cur = getFilePointer();
  785. if ((read()) != '\n') {
  786. seek(cur);
  787. }
  788. break;
  789. default:
  790. input.append((char)c);
  791. break;
  792. }
  793. }
  794. if ((c == -1) && (input.length() == 0)) {
  795. return null;
  796. }
  797. return input.toString();
  798. }
  799. /**
  800. * Reads in a string from this file. The string has been encoded
  801. * using a
  802. * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  803. * format.
  804. * <p>
  805. * The first two bytes are read, starting from the current file
  806. * pointer, as if by
  807. * <code>readUnsignedShort</code>. This value gives the number of
  808. * following bytes that are in the encoded string, not
  809. * the length of the resulting string. The following bytes are then
  810. * interpreted as bytes encoding characters in the modified UTF-8 format
  811. * and are converted into characters.
  812. * <p>
  813. * This method blocks until all the bytes are read, the end of the
  814. * stream is detected, or an exception is thrown.
  815. *
  816. * @return a Unicode string.
  817. * @exception EOFException if this file reaches the end before
  818. * reading all the bytes.
  819. * @exception IOException if an I/O error occurs.
  820. * @exception UTFDataFormatException if the bytes do not represent
  821. * valid modified UTF-8 encoding of a Unicode string.
  822. * @see java.io.RandomAccessFile#readUnsignedShort()
  823. */
  824. public final String readUTF() throws IOException {
  825. return DataInputStream.readUTF(this);
  826. }
  827. /**
  828. * Writes a <code>boolean</code> to the file as a one-byte value. The
  829. * value <code>true</code> is written out as the value
  830. * <code>(byte)1</code> the value <code>false</code> is written out
  831. * as the value <code>(byte)0</code>. The write starts at
  832. * the current position of the file pointer.
  833. *
  834. * @param v a <code>boolean</code> value to be written.
  835. * @exception IOException if an I/O error occurs.
  836. */
  837. public final void writeBoolean(boolean v) throws IOException {
  838. write(v ? 1 : 0);
  839. //written++;
  840. }
  841. /**
  842. * Writes a <code>byte</code> to the file as a one-byte value. The
  843. * write starts at the current position of the file pointer.
  844. *
  845. * @param v a <code>byte</code> value to be written.
  846. * @exception IOException if an I/O error occurs.
  847. */
  848. public final void writeByte(int v) throws IOException {
  849. write(v);
  850. //written++;
  851. }
  852. /**
  853. * Writes a <code>short</code> to the file as two bytes, high byte first.
  854. * The write starts at the current position of the file pointer.
  855. *
  856. * @param v a <code>short</code> to be written.
  857. * @exception IOException if an I/O error occurs.
  858. */
  859. public final void writeShort(int v) throws IOException {
  860. write((v >>> 8) & 0xFF);
  861. write((v >>> 0) & 0xFF);
  862. //written += 2;
  863. }
  864. /**
  865. * Writes a <code>char</code> to the file as a two-byte value, high
  866. * byte first. The write starts at the current position of the
  867. * file pointer.
  868. *
  869. * @param v a <code>char</code> value to be written.
  870. * @exception IOException if an I/O error occurs.
  871. */
  872. public final void writeChar(int v) throws IOException {
  873. write((v >>> 8) & 0xFF);
  874. write((v >>> 0) & 0xFF);
  875. //written += 2;
  876. }
  877. /**
  878. * Writes an <code>int</code> to the file as four bytes, high byte first.
  879. * The write starts at the current position of the file pointer.
  880. *
  881. * @param v an <code>int</code> to be written.
  882. * @exception IOException if an I/O error occurs.
  883. */
  884. public final void writeInt(int v) throws IOException {
  885. write((v >>> 24) & 0xFF);
  886. write((v >>> 16) & 0xFF);
  887. write((v >>> 8) & 0xFF);
  888. write((v >>> 0) & 0xFF);
  889. //written += 4;
  890. }
  891. /**
  892. * Writes a <code>long</code> to the file as eight bytes, high byte first.
  893. * The write starts at the current position of the file pointer.
  894. *
  895. * @param v a <code>long</code> to be written.
  896. * @exception IOException if an I/O error occurs.
  897. */
  898. public final void writeLong(long v) throws IOException {
  899. write((int)(v >>> 56) & 0xFF);
  900. write((int)(v >>> 48) & 0xFF);
  901. write((int)(v >>> 40) & 0xFF);
  902. write((int)(v >>> 32) & 0xFF);
  903. write((int)(v >>> 24) & 0xFF);
  904. write((int)(v >>> 16) & 0xFF);
  905. write((int)(v >>> 8) & 0xFF);
  906. write((int)(v >>> 0) & 0xFF);
  907. //written += 8;
  908. }
  909. /**
  910. * Converts the float argument to an <code>int</code> using the
  911. * <code>floatToIntBits</code> method in class <code>Float</code>,
  912. * and then writes that <code>int</code> value to the file as a
  913. * four-byte quantity, high byte first. The write starts at the
  914. * current position of the file pointer.
  915. *
  916. * @param v a <code>float</code> value to be written.
  917. * @exception IOException if an I/O error occurs.
  918. * @see java.lang.Float#floatToIntBits(float)
  919. */
  920. public final void writeFloat(float v) throws IOException {
  921. writeInt(Float.floatToIntBits(v));
  922. }
  923. /**
  924. * Converts the double argument to a <code>long</code> using the
  925. * <code>doubleToLongBits</code> method in class <code>Double</code>,
  926. * and then writes that <code>long</code> value to the file as an
  927. * eight-byte quantity, high byte first. The write starts at the current
  928. * position of the file pointer.
  929. *
  930. * @param v a <code>double</code> value to be written.
  931. * @exception IOException if an I/O error occurs.
  932. * @see java.lang.Double#doubleToLongBits(double)
  933. */
  934. public final void writeDouble(double v) throws IOException {
  935. writeLong(Double.doubleToLongBits(v));
  936. }
  937. /**
  938. * Writes the string to the file as a sequence of bytes. Each
  939. * character in the string is written out, in sequence, by discarding
  940. * its high eight bits. The write starts at the current position of
  941. * the file pointer.
  942. *
  943. * @param s a string of bytes to be written.
  944. * @exception IOException if an I/O error occurs.
  945. */
  946. public final void writeBytes(String s) throws IOException {
  947. int len = s.length();
  948. byte[] b = new byte[len];
  949. s.getBytes(0, len, b, 0);
  950. writeBytes(b, 0, len);
  951. }
  952. /**
  953. * Writes a string to the file as a sequence of characters. Each
  954. * character is written to the data output stream as if by the
  955. * <code>writeChar</code> method. The write starts at the current
  956. * position of the file pointer.
  957. *
  958. * @param s a <code>String</code> value to be written.
  959. * @exception IOException if an I/O error occurs.
  960. * @see java.io.RandomAccessFile#writeChar(int)
  961. */
  962. public final void writeChars(String s) throws IOException {
  963. int clen = s.length();
  964. int blen = 2*clen;
  965. byte[] b = new byte[blen];
  966. char[] c = new char[clen];
  967. s.getChars(0, clen, c, 0);
  968. for (int i = 0, j = 0; i < clen; i++) {
  969. b[j++] = (byte)(c[i] >>> 8);
  970. b[j++] = (byte)(c[i] >>> 0);
  971. }
  972. writeBytes(b, 0, blen);
  973. }
  974. /**
  975. * Writes a string to the file using
  976. * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
  977. * encoding in a machine-independent manner.
  978. * <p>
  979. * First, two bytes are written to the file, starting at the
  980. * current file pointer, as if by the
  981. * <code>writeShort</code> method giving the number of bytes to
  982. * follow. This value is the number of bytes actually written out,
  983. * not the length of the string. Following the length, each character
  984. * of the string is output, in sequence, using the modified UTF-8 encoding
  985. * for each character.
  986. *
  987. * @param str a string to be written.
  988. * @exception IOException if an I/O error occurs.
  989. */
  990. public final void writeUTF(String str) throws IOException {
  991. DataOutputStream.writeUTF(str, this);
  992. }
  993. private static native void initIDs();
  994. private native void close0() throws IOException;
  995. static {
  996. initIDs();
  997. }
  998. }