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 * Instances of this class support both reading and writing to a
34 * random access file. A random access file behaves like a large
35 * array of bytes stored in the file system. There is a kind of cursor,
36 * or index into the implied array, called the <em>file pointer</em>;
37 * input operations read bytes starting at the file pointer and advance
38 * the file pointer past the bytes read. If the random access file is
39 * created in read/write mode, then output operations are also available;
40 * output operations write bytes starting at the file pointer and advance
41 * the file pointer past the bytes written. Output operations that write
42 * past the current end of the implied array cause the array to be
43 * extended. The file pointer can be read by the
44 * {@code getFilePointer} method and set by the {@code seek}
45 * method.
46 * <p>
47 * It is generally true of all the reading routines in this class that
48 * if end-of-file is reached before the desired number of bytes has been
49 * read, an {@code EOFException} (which is a kind of
50 * {@code IOException}) is thrown. If any byte cannot be read for
51 * any reason other than end-of-file, an {@code IOException} other
52 * than {@code EOFException} is thrown. In particular, an
53 * {@code IOException} may be thrown if the stream has been closed.
54 *
55 * @author unascribed
56 * @since JDK1.0
57 */
58
59 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
60
61 private FileDescriptor fd;
62 private FileChannel channel = null;
63 private boolean rw;
64
65 private Object closeLock = new Object();
66 private volatile boolean closed = false;
67
68 private static final int O_RDONLY = 1;
69 private static final int O_RDWR = 2;
70 private static final int O_SYNC = 4;
71 private static final int O_DSYNC = 8;
72
73 /**
74 * Creates a random access file stream to read from, and optionally
75 * to write to, a file with the specified name. A new
76 * {@link FileDescriptor} object is created to represent the
77 * connection to the file.
78 *
79 * <p> The <tt>mode</tt> argument specifies the access mode with which the
80 * file is to be opened. The permitted values and their meanings are as
81 * specified for the <a
82 * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
83 *
213 imode = -1;
214 }
215 }
216 if (imode < 0)
217 throw new IllegalArgumentException("Illegal mode \"" + mode
218 + "\" must be one of "
219 + "\"r\", \"rw\", \"rws\","
220 + " or \"rwd\"");
221 SecurityManager security = System.getSecurityManager();
222 if (security != null) {
223 security.checkRead(name);
224 if (rw) {
225 security.checkWrite(name);
226 }
227 }
228 if (name == null) {
229 throw new NullPointerException();
230 }
231 fd = new FileDescriptor();
232 fd.attach(this);
233 open(name, imode);
234 }
235
236 /**
237 * Returns the opaque file descriptor object associated with this
238 * stream. </p>
239 *
240 * @return the file descriptor object associated with this stream.
241 * @exception IOException if an I/O error occurs.
242 * @see java.io.FileDescriptor
243 */
244 public final FileDescriptor getFD() throws IOException {
245 if (fd != null) {
246 return fd;
247 }
248 throw new IOException();
249 }
250
251 /**
252 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
253 * object associated with this file.
254 *
255 * <p> The {@link java.nio.channels.FileChannel#position()
256 * position} of the returned channel will always be equal to
257 * this object's file-pointer offset as returned by the {@link
258 * #getFilePointer getFilePointer} method. Changing this object's
259 * file-pointer offset, whether explicitly or by reading or writing bytes,
260 * will change the position of the channel, and vice versa. Changing the
261 * file's length via this object will change the length seen via the file
262 * channel, and vice versa.
263 *
264 * @return the file channel associated with this file
265 *
266 * @since 1.4
267 * @spec JSR-51
268 */
269 public final FileChannel getChannel() {
270 synchronized (this) {
271 if (channel == null) {
272 channel = FileChannelImpl.open(fd, true, rw, this);
273 }
274 return channel;
275 }
276 }
277
278 /**
279 * Opens a file and returns the file descriptor. The file is
280 * opened in read-write mode if the O_RDWR bit in {@code mode}
281 * is true, else the file is opened as read-only.
282 * If the {@code name} refers to a directory, an IOException
283 * is thrown.
284 *
285 * @param name the name of the file
286 * @param mode the mode flags, a combination of the O_ constants
287 * defined above
288 */
289 private native void open(String name, int mode)
290 throws FileNotFoundException;
291
292 // 'Read' primitives
293
294 /**
295 * Reads a byte of data from this file. The byte is returned as an
296 * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
297 * method blocks if no input is yet available.
298 * <p>
299 * Although {@code RandomAccessFile} is not a subclass of
300 * {@code InputStream}, this method behaves in exactly the same
301 * way as the {@link InputStream#read()} method of
302 * {@code InputStream}.
303 *
304 * @return the next byte of data, or {@code -1} if the end of the
305 * file has been reached.
306 * @exception IOException if an I/O error occurs. Not thrown if
307 * end-of-file has been reached.
308 */
309 public native int read() throws IOException;
310
311 /**
312 * Reads a sub array as a sequence of bytes.
313 * @param b the buffer into which the data is read.
314 * @param off the start offset of the data.
315 * @param len the number of bytes to read.
316 * @exception IOException If an I/O error has occurred.
317 */
318 private native int readBytes(byte b[], int off, int len) throws IOException;
319
320 /**
321 * Reads up to {@code len} bytes of data from this file into an
322 * array of bytes. This method blocks until at least one byte of input
323 * is available.
324 * <p>
325 * Although {@code RandomAccessFile} is not a subclass of
326 * {@code InputStream}, this method behaves in exactly the
327 * same way as the {@link InputStream#read(byte[], int, int)} method of
328 * {@code InputStream}.
329 *
330 * @param b the buffer into which the data is read.
331 * @param off the start offset in array {@code b}
332 * at which the data is written.
333 * @param len the maximum number of bytes read.
334 * @return the total number of bytes read into the buffer, or
335 * {@code -1} if there is no more data because the end of
336 * the file has been reached.
337 * @exception IOException If the first byte cannot be read for any reason
338 * other than end of file, or if the random access file has been closed, or if
437 len = length();
438 newpos = pos + n;
439 if (newpos > len) {
440 newpos = len;
441 }
442 seek(newpos);
443
444 /* return the actual number of bytes skipped */
445 return (int) (newpos - pos);
446 }
447
448 // 'Write' primitives
449
450 /**
451 * Writes the specified byte to this file. The write starts at
452 * the current file pointer.
453 *
454 * @param b the {@code byte} to be written.
455 * @exception IOException if an I/O error occurs.
456 */
457 public native void write(int b) throws IOException;
458
459 /**
460 * Writes a sub array as a sequence of bytes.
461 * @param b the data to be written
462
463 * @param off the start offset in the data
464 * @param len the number of bytes that are written
465 * @exception IOException If an I/O error has occurred.
466 */
467 private native void writeBytes(byte b[], int off, int len) throws IOException;
468
469 /**
470 * Writes {@code b.length} bytes from the specified byte array
471 * to this file, starting at the current file pointer.
472 *
473 * @param b the data.
474 * @exception IOException if an I/O error occurs.
475 */
476 public void write(byte b[]) throws IOException {
477 writeBytes(b, 0, b.length);
478 }
479
480 /**
481 * Writes {@code len} bytes from the specified byte array
482 * starting at offset {@code off} to this file.
483 *
484 * @param b the data.
485 * @param off the start offset in the data.
486 * @param len the number of bytes to write.
487 * @exception IOException if an I/O error occurs.
|
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 import sun.misc.IoTrace;
31 import sun.misc.IoTraceContext;
32
33
34 /**
35 * Instances of this class support both reading and writing to a
36 * random access file. A random access file behaves like a large
37 * array of bytes stored in the file system. There is a kind of cursor,
38 * or index into the implied array, called the <em>file pointer</em>;
39 * input operations read bytes starting at the file pointer and advance
40 * the file pointer past the bytes read. If the random access file is
41 * created in read/write mode, then output operations are also available;
42 * output operations write bytes starting at the file pointer and advance
43 * the file pointer past the bytes written. Output operations that write
44 * past the current end of the implied array cause the array to be
45 * extended. The file pointer can be read by the
46 * {@code getFilePointer} method and set by the {@code seek}
47 * method.
48 * <p>
49 * It is generally true of all the reading routines in this class that
50 * if end-of-file is reached before the desired number of bytes has been
51 * read, an {@code EOFException} (which is a kind of
52 * {@code IOException}) is thrown. If any byte cannot be read for
53 * any reason other than end-of-file, an {@code IOException} other
54 * than {@code EOFException} is thrown. In particular, an
55 * {@code IOException} may be thrown if the stream has been closed.
56 *
57 * @author unascribed
58 * @since JDK1.0
59 */
60
61 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
62
63 private FileDescriptor fd;
64 private FileChannel channel = null;
65 private boolean rw;
66 private final String path;
67
68 private Object closeLock = new Object();
69 private volatile boolean closed = false;
70
71 private static final int O_RDONLY = 1;
72 private static final int O_RDWR = 2;
73 private static final int O_SYNC = 4;
74 private static final int O_DSYNC = 8;
75
76 /**
77 * Creates a random access file stream to read from, and optionally
78 * to write to, a file with the specified name. A new
79 * {@link FileDescriptor} object is created to represent the
80 * connection to the file.
81 *
82 * <p> The <tt>mode</tt> argument specifies the access mode with which the
83 * file is to be opened. The permitted values and their meanings are as
84 * specified for the <a
85 * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
86 *
216 imode = -1;
217 }
218 }
219 if (imode < 0)
220 throw new IllegalArgumentException("Illegal mode \"" + mode
221 + "\" must be one of "
222 + "\"r\", \"rw\", \"rws\","
223 + " or \"rwd\"");
224 SecurityManager security = System.getSecurityManager();
225 if (security != null) {
226 security.checkRead(name);
227 if (rw) {
228 security.checkWrite(name);
229 }
230 }
231 if (name == null) {
232 throw new NullPointerException();
233 }
234 fd = new FileDescriptor();
235 fd.attach(this);
236 this.path = name;
237 open(name, imode);
238 }
239
240 /**
241 * Returns the opaque file descriptor object associated with this
242 * stream. </p>
243 *
244 * @return the file descriptor object associated with this stream.
245 * @exception IOException if an I/O error occurs.
246 * @see java.io.FileDescriptor
247 */
248 public final FileDescriptor getFD() throws IOException {
249 if (fd != null) {
250 return fd;
251 }
252 throw new IOException();
253 }
254
255 /**
256 * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
257 * object associated with this file.
258 *
259 * <p> The {@link java.nio.channels.FileChannel#position()
260 * position} of the returned channel will always be equal to
261 * this object's file-pointer offset as returned by the {@link
262 * #getFilePointer getFilePointer} method. Changing this object's
263 * file-pointer offset, whether explicitly or by reading or writing bytes,
264 * will change the position of the channel, and vice versa. Changing the
265 * file's length via this object will change the length seen via the file
266 * channel, and vice versa.
267 *
268 * @return the file channel associated with this file
269 *
270 * @since 1.4
271 * @spec JSR-51
272 */
273 public final FileChannel getChannel() {
274 synchronized (this) {
275 if (channel == null) {
276 channel = FileChannelImpl.open(fd, path, true, rw, this);
277 }
278 return channel;
279 }
280 }
281
282 /**
283 * Opens a file and returns the file descriptor. The file is
284 * opened in read-write mode if the O_RDWR bit in {@code mode}
285 * is true, else the file is opened as read-only.
286 * If the {@code name} refers to a directory, an IOException
287 * is thrown.
288 *
289 * @param name the name of the file
290 * @param mode the mode flags, a combination of the O_ constants
291 * defined above
292 */
293 private native void open(String name, int mode)
294 throws FileNotFoundException;
295
296 // 'Read' primitives
297
298 /**
299 * Reads a byte of data from this file. The byte is returned as an
300 * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
301 * method blocks if no input is yet available.
302 * <p>
303 * Although {@code RandomAccessFile} is not a subclass of
304 * {@code InputStream}, this method behaves in exactly the same
305 * way as the {@link InputStream#read()} method of
306 * {@code InputStream}.
307 *
308 * @return the next byte of data, or {@code -1} if the end of the
309 * file has been reached.
310 * @exception IOException if an I/O error occurs. Not thrown if
311 * end-of-file has been reached.
312 */
313 public int read() throws IOException {
314 IoTraceContext traceContext = IoTrace.fileReadBegin(path);
315 int v = 0;
316 try {
317 v = read0();
318 } finally {
319 IoTrace.fileReadEnd(traceContext, v == -1 ? 0 : 1);
320 }
321 return v;
322 }
323
324 private native int read0() throws IOException;
325
326 /**
327 * Reads a sub array as a sequence of bytes.
328 * @param b the buffer into which the data is read.
329 * @param off the start offset of the data.
330 * @param len the number of bytes to read.
331 * @exception IOException If an I/O error has occurred.
332 */
333 private int readBytes(byte b[], int off, int len) throws IOException {
334 IoTraceContext traceContext = IoTrace.fileReadBegin(path);
335 int v = 0;
336 try {
337 v = readBytes0(b, off, len);
338 } finally {
339 IoTrace.fileReadEnd(traceContext, v);
340 }
341 return v;
342 }
343
344 private native int readBytes0(byte b[], int off, int len) throws IOException;
345
346 /**
347 * Reads up to {@code len} bytes of data from this file into an
348 * array of bytes. This method blocks until at least one byte of input
349 * is available.
350 * <p>
351 * Although {@code RandomAccessFile} is not a subclass of
352 * {@code InputStream}, this method behaves in exactly the
353 * same way as the {@link InputStream#read(byte[], int, int)} method of
354 * {@code InputStream}.
355 *
356 * @param b the buffer into which the data is read.
357 * @param off the start offset in array {@code b}
358 * at which the data is written.
359 * @param len the maximum number of bytes read.
360 * @return the total number of bytes read into the buffer, or
361 * {@code -1} if there is no more data because the end of
362 * the file has been reached.
363 * @exception IOException If the first byte cannot be read for any reason
364 * other than end of file, or if the random access file has been closed, or if
463 len = length();
464 newpos = pos + n;
465 if (newpos > len) {
466 newpos = len;
467 }
468 seek(newpos);
469
470 /* return the actual number of bytes skipped */
471 return (int) (newpos - pos);
472 }
473
474 // 'Write' primitives
475
476 /**
477 * Writes the specified byte to this file. The write starts at
478 * the current file pointer.
479 *
480 * @param b the {@code byte} to be written.
481 * @exception IOException if an I/O error occurs.
482 */
483 public void write(int b) throws IOException {
484 IoTraceContext traceContext = IoTrace.fileWriteBegin(path);
485 int v = 0;
486 try {
487 write0(b);
488 v = 1;
489 } finally {
490 IoTrace.fileWriteEnd(traceContext, v);
491 }
492 }
493
494 private native void write0(int b) throws IOException;
495
496 /**
497 * Writes a sub array as a sequence of bytes.
498 * @param b the data to be written
499 * @param off the start offset in the data
500 * @param len the number of bytes that are written
501 * @exception IOException If an I/O error has occurred.
502 */
503 private void writeBytes(byte b[], int off, int len) throws IOException {
504 IoTraceContext traceContext = IoTrace.fileWriteBegin(path);
505 int v = 0;
506 try {
507 writeBytes0(b, off, len);
508 v = len;
509 } finally {
510 IoTrace.fileWriteEnd(traceContext, v);
511 }
512 }
513
514 private native void writeBytes0(byte b[], int off, int len) throws IOException;
515
516 /**
517 * Writes {@code b.length} bytes from the specified byte array
518 * to this file, starting at the current file pointer.
519 *
520 * @param b the data.
521 * @exception IOException if an I/O error occurs.
522 */
523 public void write(byte b[]) throws IOException {
524 writeBytes(b, 0, b.length);
525 }
526
527 /**
528 * Writes {@code len} bytes from the specified byte array
529 * starting at offset {@code off} to this file.
530 *
531 * @param b the data.
532 * @param off the start offset in the data.
533 * @param len the number of bytes to write.
534 * @exception IOException if an I/O error occurs.
|