1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.io;
28 
29 import dalvik.annotation.optimization.ReachabilitySensitive;
30 import java.nio.channels.FileChannel;
31 import sun.nio.ch.FileChannelImpl;
32 import android.system.Os;
33 import android.system.ErrnoException;
34 import android.system.OsConstants;
35 
36 import dalvik.system.CloseGuard;
37 import libcore.io.IoBridge;
38 import libcore.io.IoTracker;
39 import libcore.io.IoUtils;
40 import libcore.io.Libcore;
41 import static android.system.OsConstants.*;
42 
43 
44 /**
45  * Instances of this class support both reading and writing to a
46  * random access file. A random access file behaves like a large
47  * array of bytes stored in the file system. There is a kind of cursor,
48  * or index into the implied array, called the <em>file pointer</em>;
49  * input operations read bytes starting at the file pointer and advance
50  * the file pointer past the bytes read. If the random access file is
51  * created in read/write mode, then output operations are also available;
52  * output operations write bytes starting at the file pointer and advance
53  * the file pointer past the bytes written. Output operations that write
54  * past the current end of the implied array cause the array to be
55  * extended. The file pointer can be read by the
56  * {@code getFilePointer} method and set by the {@code seek}
57  * method.
58  * <p>
59  * It is generally true of all the reading routines in this class that
60  * if end-of-file is reached before the desired number of bytes has been
61  * read, an {@code EOFException} (which is a kind of
62  * {@code IOException}) is thrown. If any byte cannot be read for
63  * any reason other than end-of-file, an {@code IOException} other
64  * than {@code EOFException} is thrown. In particular, an
65  * {@code IOException} may be thrown if the stream has been closed.
66  *
67  * @author  unascribed
68  * @since   JDK1.0
69  */
70 
71 public class RandomAccessFile implements DataOutput, DataInput, Closeable {
72 
73     // BEGIN Android-added: CloseGuard and some helper fields for Android changes in this file.
74     @ReachabilitySensitive
75     private final CloseGuard guard = CloseGuard.get();
76     private final byte[] scratch = new byte[8];
77 
78     private static final int FLUSH_NONE = 0;
79     private static final int FLUSH_FSYNC = 1;
80     private static final int FLUSH_FDATASYNC = 2;
81     private int flushAfterWrite = FLUSH_NONE;
82 
83     private int mode;
84     // END Android-added: CloseGuard and some helper fields for Android changes in this file.
85 
86     // Android-added: @ReachabilitySensitive
87     @ReachabilitySensitive
88     private FileDescriptor fd;
89     private FileChannel channel = null;
90     private boolean rw;
91 
92     /**
93      * The path of the referenced file
94      * (null if the stream is created with a file descriptor)
95      */
96     private final String path;
97 
98     private Object closeLock = new Object();
99     private volatile boolean closed = false;
100 
101     // BEGIN Android-added: IoTracker.
102     /**
103      * A single tracker to track both read and write. The tracker resets when the operation
104      * performed is different from the operation last performed.
105      */
106     private final IoTracker ioTracker = new IoTracker();
107     // END Android-added: IoTracker.
108 
109     /**
110      * Creates a random access file stream to read from, and optionally
111      * to write to, a file with the specified name. A new
112      * {@link FileDescriptor} object is created to represent the
113      * connection to the file.
114      *
115      * <p> The <tt>mode</tt> argument specifies the access mode with which the
116      * file is to be opened.  The permitted values and their meanings are as
117      * specified for the <a
118      * href="#mode"><tt>RandomAccessFile(File,String)</tt></a> constructor.
119      *
120      * <p>
121      * If there is a security manager, its {@code checkRead} method
122      * is called with the {@code name} argument
123      * as its argument to see if read access to the file is allowed.
124      * If the mode allows writing, the security manager's
125      * {@code checkWrite} method
126      * is also called with the {@code name} argument
127      * as its argument to see if write access to the file is allowed.
128      *
129      * @param      name   the system-dependent filename
130      * @param      mode   the access <a href="#mode">mode</a>
131      * @exception  IllegalArgumentException  if the mode argument is not equal
132      *               to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
133      *               <tt>"rwd"</tt>
134      * @exception FileNotFoundException
135      *            if the mode is <tt>"r"</tt> but the given string does not
136      *            denote an existing regular file, or if the mode begins with
137      *            <tt>"rw"</tt> but the given string does not denote an
138      *            existing, writable regular file and a new regular file of
139      *            that name cannot be created, or if some other error occurs
140      *            while opening or creating the file
141      * @exception  SecurityException         if a security manager exists and its
142      *               {@code checkRead} method denies read access to the file
143      *               or the mode is "rw" and the security manager's
144      *               {@code checkWrite} method denies write access to the file
145      * @see        java.lang.SecurityException
146      * @see        java.lang.SecurityManager#checkRead(java.lang.String)
147      * @see        java.lang.SecurityManager#checkWrite(java.lang.String)
148      * @revised 1.4
149      * @spec JSR-51
150      */
RandomAccessFile(String name, String mode)151     public RandomAccessFile(String name, String mode)
152         throws FileNotFoundException
153     {
154         this(name != null ? new File(name) : null, mode);
155     }
156 
157     /**
158      * Creates a random access file stream to read from, and optionally to
159      * write to, the file specified by the {@link File} argument.  A new {@link
160      * FileDescriptor} object is created to represent this file connection.
161      *
162      * <p>The <a name="mode"><tt>mode</tt></a> argument specifies the access mode
163      * in which the file is to be opened.  The permitted values and their
164      * meanings are:
165      *
166      * <table summary="Access mode permitted values and meanings">
167      * <tr><th align="left">Value</th><th align="left">Meaning</th></tr>
168      * <tr><td valign="top"><tt>"r"</tt></td>
169      *     <td> Open for reading only.  Invoking any of the <tt>write</tt>
170      *     methods of the resulting object will cause an {@link
171      *     java.io.IOException} to be thrown. </td></tr>
172      * <tr><td valign="top"><tt>"rw"</tt></td>
173      *     <td> Open for reading and writing.  If the file does not already
174      *     exist then an attempt will be made to create it. </td></tr>
175      * <tr><td valign="top"><tt>"rws"</tt></td>
176      *     <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
177      *     require that every update to the file's content or metadata be
178      *     written synchronously to the underlying storage device.  </td></tr>
179      * <tr><td valign="top"><tt>"rwd"&nbsp;&nbsp;</tt></td>
180      *     <td> Open for reading and writing, as with <tt>"rw"</tt>, and also
181      *     require that every update to the file's content be written
182      *     synchronously to the underlying storage device. </td></tr>
183      * </table>
184      *
185      * The <tt>"rws"</tt> and <tt>"rwd"</tt> modes work much like the {@link
186      * java.nio.channels.FileChannel#force(boolean) force(boolean)} method of
187      * the {@link java.nio.channels.FileChannel} class, passing arguments of
188      * <tt>true</tt> and <tt>false</tt>, respectively, except that they always
189      * apply to every I/O operation and are therefore often more efficient.  If
190      * the file resides on a local storage device then when an invocation of a
191      * method of this class returns it is guaranteed that all changes made to
192      * the file by that invocation will have been written to that device.  This
193      * is useful for ensuring that critical information is not lost in the
194      * event of a system crash.  If the file does not reside on a local device
195      * then no such guarantee is made.
196      *
197      * <p>The <tt>"rwd"</tt> mode can be used to reduce the number of I/O
198      * operations performed.  Using <tt>"rwd"</tt> only requires updates to the
199      * file's content to be written to storage; using <tt>"rws"</tt> requires
200      * updates to both the file's content and its metadata to be written, which
201      * generally requires at least one more low-level I/O operation.
202      *
203      * <p>If there is a security manager, its {@code checkRead} method is
204      * called with the pathname of the {@code file} argument as its
205      * argument to see if read access to the file is allowed.  If the mode
206      * allows writing, the security manager's {@code checkWrite} method is
207      * also called with the path argument to see if write access to the file is
208      * allowed.
209      *
210      * @param      file   the file object
211      * @param      mode   the access mode, as described
212      *                    <a href="#mode">above</a>
213      * @exception  IllegalArgumentException  if the mode argument is not equal
214      *               to one of <tt>"r"</tt>, <tt>"rw"</tt>, <tt>"rws"</tt>, or
215      *               <tt>"rwd"</tt>
216      * @exception FileNotFoundException
217      *            if the mode is <tt>"r"</tt> but the given file object does
218      *            not denote an existing regular file, or if the mode begins
219      *            with <tt>"rw"</tt> but the given file object does not denote
220      *            an existing, writable regular file and a new regular file of
221      *            that name cannot be created, or if some other error occurs
222      *            while opening or creating the file
223      * @exception  SecurityException         if a security manager exists and its
224      *               {@code checkRead} method denies read access to the file
225      *               or the mode is "rw" and the security manager's
226      *               {@code checkWrite} method denies write access to the file
227      * @see        java.lang.SecurityManager#checkRead(java.lang.String)
228      * @see        java.lang.SecurityManager#checkWrite(java.lang.String)
229      * @see        java.nio.channels.FileChannel#force(boolean)
230      * @revised 1.4
231      * @spec JSR-51
232      */
RandomAccessFile(File file, String mode)233     public RandomAccessFile(File file, String mode)
234         throws FileNotFoundException
235     {
236         // Android-changed: delegate to constructor which controls O_CLOEXEC.
237         this(file, mode, /* setCloExecFlag= */ false);
238     }
239 
240     /**
241      * Identical to {@link #RandomAccessFile(File, String)}, but with a capability to control
242      * O_CLOEXEC flag of file descriptor.
243      *
244      * @param setCloExecFlag if true file descriptor will be opened with O_CLOEXE flag set
245      * @hide
246      */
247     // Android-changed: added an extra argument to set O_CLOEXEC.
RandomAccessFile(File file, String mode, boolean setCloExecFlag)248     public RandomAccessFile(File file, String mode, boolean setCloExecFlag)
249             throws FileNotFoundException {
250         String name = (file != null ? file.getPath() : null);
251         int imode = -1;
252         if (mode.equals("r")) {
253             imode = O_RDONLY;
254         } else if (mode.startsWith("rw")) {
255             // Android-changed: Added. O_CREAT
256             // imode = O_RDWR;
257             imode = O_RDWR | O_CREAT;
258             rw = true;
259             if (mode.length() > 2) {
260                 if (mode.equals("rws")) {
261                     // Android-changed: For performance reasons, use fsync after each write.
262                     // RandomAccessFile.write may result in multiple write syscalls,
263                     // O_SYNC/O_DSYNC flags will cause a blocking wait on each syscall. Replacing
264                     // them with single fsync/fdatasync call gives better performance with only
265                     // minor decrease in reliability.
266                     // imode |= O_SYNC;
267                     flushAfterWrite = FLUSH_FSYNC;
268                 } else if (mode.equals("rwd")) {
269                     // Android-changed: For performance reasons, use fdatasync after each write.
270                     // imode |= O_DSYNC;
271                     flushAfterWrite = FLUSH_FDATASYNC;
272                 } else {
273                     imode = -1;
274                 }
275             }
276         }
277         if (imode < 0) {
278             throw new IllegalArgumentException("Illegal mode \"" + mode
279                                                + "\" must be one of "
280                                                + "\"r\", \"rw\", \"rws\","
281                                                + " or \"rwd\"");
282         }
283         // Android-removed: do not use legacy security code
284         /*
285         SecurityManager security = System.getSecurityManager();
286         if (security != null) {
287             security.checkRead(name);
288             if (rw) {
289                 security.checkWrite(name);
290             }
291         }
292         */
293         if (name == null) {
294             // Android-changed: different exception message in ctor when file == null.
295             // throw new NullPointerException();
296             throw new NullPointerException("file == null");
297         }
298         if (file.isInvalid()) {
299             throw new FileNotFoundException("Invalid file path");
300         }
301         this.path = name;
302         // Android-added: set O_CLOEXEC flag if requested.
303         imode = setCloExecFlag ? imode | O_CLOEXEC : imode;
304         this.mode = imode;
305 
306         // BEGIN Android-changed: Use IoBridge.open() instead of open.
307         fd = IoBridge.open(name, imode);
308         IoUtils.setFdOwner(fd, this);
309         maybeSync();
310         guard.open("close");
311         // END Android-changed: Use IoBridge.open() instead of open.
312     }
313 
314     // BEGIN Android-added: Sync after rws/rwd write
maybeSync()315     private void maybeSync() {
316         if (flushAfterWrite == FLUSH_FSYNC) {
317             try {
318                 fd.sync();
319             } catch (IOException e) {
320                 // Ignored
321             }
322         } else if (flushAfterWrite == FLUSH_FDATASYNC) {
323             try {
324                 Os.fdatasync(fd);
325             } catch (ErrnoException e) {
326                 // Ignored
327             }
328         }
329     }
330     // END Android-added: Sync after rws/rwd write
331 
332     /**
333      * Returns the opaque file descriptor object associated with this
334      * stream.
335      *
336      * @return     the file descriptor object associated with this stream.
337      * @exception  IOException  if an I/O error occurs.
338      * @see        java.io.FileDescriptor
339      */
getFD()340     public final FileDescriptor getFD() throws IOException {
341         if (fd != null) {
342             return fd;
343         }
344         throw new IOException();
345     }
346 
347     /**
348      * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
349      * object associated with this file.
350      *
351      * <p> The {@link java.nio.channels.FileChannel#position()
352      * position} of the returned channel will always be equal to
353      * this object's file-pointer offset as returned by the {@link
354      * #getFilePointer getFilePointer} method.  Changing this object's
355      * file-pointer offset, whether explicitly or by reading or writing bytes,
356      * will change the position of the channel, and vice versa.  Changing the
357      * file's length via this object will change the length seen via the file
358      * channel, and vice versa.
359      *
360      * @return  the file channel associated with this file
361      *
362      * @since 1.4
363      * @spec JSR-51
364      */
getChannel()365     public final FileChannel getChannel() {
366         synchronized (this) {
367             if (channel == null) {
368                 channel = FileChannelImpl.open(fd, path, true, rw, this);
369             }
370             return channel;
371         }
372     }
373 
374     /**
375      * Reads a byte of data from this file. The byte is returned as an
376      * integer in the range 0 to 255 ({@code 0x00-0x0ff}). This
377      * method blocks if no input is yet available.
378      * <p>
379      * Although {@code RandomAccessFile} is not a subclass of
380      * {@code InputStream}, this method behaves in exactly the same
381      * way as the {@link InputStream#read()} method of
382      * {@code InputStream}.
383      *
384      * @return     the next byte of data, or {@code -1} if the end of the
385      *             file has been reached.
386      * @exception  IOException  if an I/O error occurs. Not thrown if
387      *                          end-of-file has been reached.
388      */
read()389     public int read() throws IOException {
390         // Android-changed: Implement on top of libcore os API.
391         // return read0();
392         return (read(scratch, 0, 1) != -1) ? scratch[0] & 0xff : -1;
393     }
394 
395     /**
396      * Reads a sub array as a sequence of bytes.
397      * @param b the buffer into which the data is read.
398      * @param off the start offset of the data.
399      * @param len the number of bytes to read.
400      * @exception IOException If an I/O error has occurred.
401      */
readBytes(byte b[], int off, int len)402     private int readBytes(byte b[], int off, int len) throws IOException {
403         // Android-changed: Implement on top of libcore os API.
404         ioTracker.trackIo(len, IoTracker.Mode.READ);
405         return IoBridge.read(fd, b, off, len);
406     }
407 
408     /**
409      * Reads up to {@code len} bytes of data from this file into an
410      * array of bytes. This method blocks until at least one byte of input
411      * is available.
412      * <p>
413      * Although {@code RandomAccessFile} is not a subclass of
414      * {@code InputStream}, this method behaves in exactly the
415      * same way as the {@link InputStream#read(byte[], int, int)} method of
416      * {@code InputStream}.
417      *
418      * @param      b     the buffer into which the data is read.
419      * @param      off   the start offset in array {@code b}
420      *                   at which the data is written.
421      * @param      len   the maximum number of bytes read.
422      * @return     the total number of bytes read into the buffer, or
423      *             {@code -1} if there is no more data because the end of
424      *             the file has been reached.
425      * @exception  IOException If the first byte cannot be read for any reason
426      * other than end of file, or if the random access file has been closed, or if
427      * some other I/O error occurs.
428      * @exception  NullPointerException If {@code b} is {@code null}.
429      * @exception  IndexOutOfBoundsException If {@code off} is negative,
430      * {@code len} is negative, or {@code len} is greater than
431      * {@code b.length - off}
432      */
read(byte b[], int off, int len)433     public int read(byte b[], int off, int len) throws IOException {
434         return readBytes(b, off, len);
435     }
436 
437     /**
438      * Reads up to {@code b.length} bytes of data from this file
439      * into an array of bytes. This method blocks until at least one byte
440      * of input is available.
441      * <p>
442      * Although {@code RandomAccessFile} is not a subclass of
443      * {@code InputStream}, this method behaves in exactly the
444      * same way as the {@link InputStream#read(byte[])} method of
445      * {@code InputStream}.
446      *
447      * @param      b   the buffer into which the data is read.
448      * @return     the total number of bytes read into the buffer, or
449      *             {@code -1} if there is no more data because the end of
450      *             this file has been reached.
451      * @exception  IOException If the first byte cannot be read for any reason
452      * other than end of file, or if the random access file has been closed, or if
453      * some other I/O error occurs.
454      * @exception  NullPointerException If {@code b} is {@code null}.
455      */
read(byte b[])456     public int read(byte b[]) throws IOException {
457         return readBytes(b, 0, b.length);
458     }
459 
460     /**
461      * Reads {@code b.length} bytes from this file into the byte
462      * array, starting at the current file pointer. This method reads
463      * repeatedly from the file until the requested number of bytes are
464      * read. This method blocks until the requested number of bytes are
465      * read, the end of the stream is detected, or an exception is thrown.
466      *
467      * @param      b   the buffer into which the data is read.
468      * @exception  EOFException  if this file reaches the end before reading
469      *               all the bytes.
470      * @exception  IOException   if an I/O error occurs.
471      */
readFully(byte b[])472     public final void readFully(byte b[]) throws IOException {
473         readFully(b, 0, b.length);
474     }
475 
476     /**
477      * Reads exactly {@code len} bytes from this file into the byte
478      * array, starting at the current file pointer. This method reads
479      * repeatedly from the file until the requested number of bytes are
480      * read. This method blocks until the requested number of bytes are
481      * read, the end of the stream is detected, or an exception is thrown.
482      *
483      * @param      b     the buffer into which the data is read.
484      * @param      off   the start offset of the data.
485      * @param      len   the number of bytes to read.
486      * @exception  EOFException  if this file reaches the end before reading
487      *               all the bytes.
488      * @exception  IOException   if an I/O error occurs.
489      */
readFully(byte b[], int off, int len)490     public final void readFully(byte b[], int off, int len) throws IOException {
491         int n = 0;
492         do {
493             int count = this.read(b, off + n, len - n);
494             if (count < 0)
495                 throw new EOFException();
496             n += count;
497         } while (n < len);
498     }
499 
500     /**
501      * Attempts to skip over {@code n} bytes of input discarding the
502      * skipped bytes.
503      * <p>
504      *
505      * This method may skip over some smaller number of bytes, possibly zero.
506      * This may result from any of a number of conditions; reaching end of
507      * file before {@code n} bytes have been skipped is only one
508      * possibility. This method never throws an {@code EOFException}.
509      * The actual number of bytes skipped is returned.  If {@code n}
510      * is negative, no bytes are skipped.
511      *
512      * @param      n   the number of bytes to be skipped.
513      * @return     the actual number of bytes skipped.
514      * @exception  IOException  if an I/O error occurs.
515      */
skipBytes(int n)516     public int skipBytes(int n) throws IOException {
517         long pos;
518         long len;
519         long newpos;
520 
521         if (n <= 0) {
522             return 0;
523         }
524         pos = getFilePointer();
525         len = length();
526         newpos = pos + n;
527         if (newpos > len) {
528             newpos = len;
529         }
530         seek(newpos);
531 
532         /* return the actual number of bytes skipped */
533         return (int) (newpos - pos);
534     }
535 
536     // 'Write' primitives
537 
538     /**
539      * Writes the specified byte to this file. The write starts at
540      * the current file pointer.
541      *
542      * @param      b   the {@code byte} to be written.
543      * @exception  IOException  if an I/O error occurs.
544      */
write(int b)545     public void write(int b) throws IOException {
546         // BEGIN Android-changed: Implement on top of libcore os API.
547         // write0(b);
548         scratch[0] = (byte) (b & 0xff);
549         write(scratch, 0, 1);
550         // END Android-changed: Implement on top of libcore os API.
551     }
552 
553     /**
554      * Writes a sub array as a sequence of bytes.
555      * @param b the data to be written
556 
557      * @param off the start offset in the data
558      * @param len the number of bytes that are written
559      * @exception IOException If an I/O error has occurred.
560      */
writeBytes(byte b[], int off, int len)561     private void writeBytes(byte b[], int off, int len) throws IOException {
562         // BEGIN Android-changed: Implement on top of libcore os API.
563         ioTracker.trackIo(len, IoTracker.Mode.WRITE);
564         IoBridge.write(fd, b, off, len);
565         maybeSync();
566         // END Android-changed: Implement on top of libcore os API.
567     }
568 
569     /**
570      * Writes {@code b.length} bytes from the specified byte array
571      * to this file, starting at the current file pointer.
572      *
573      * @param      b   the data.
574      * @exception  IOException  if an I/O error occurs.
575      */
write(byte b[])576     public void write(byte b[]) throws IOException {
577         writeBytes(b, 0, b.length);
578     }
579 
580     /**
581      * Writes {@code len} bytes from the specified byte array
582      * starting at offset {@code off} to this file.
583      *
584      * @param      b     the data.
585      * @param      off   the start offset in the data.
586      * @param      len   the number of bytes to write.
587      * @exception  IOException  if an I/O error occurs.
588      */
write(byte b[], int off, int len)589     public void write(byte b[], int off, int len) throws IOException {
590         writeBytes(b, off, len);
591     }
592 
593     // 'Random access' stuff
594 
595     /**
596      * Returns the current offset in this file.
597      *
598      * @return     the offset from the beginning of the file, in bytes,
599      *             at which the next read or write occurs.
600      * @exception  IOException  if an I/O error occurs.
601      */
getFilePointer()602     public long getFilePointer() throws IOException {
603         // BEGIN Android-changed: Implement on top of libcore os API.
604         try {
605             return Libcore.os.lseek(fd, 0L, SEEK_CUR);
606         } catch (ErrnoException errnoException) {
607             throw errnoException.rethrowAsIOException();
608         }
609         // END Android-changed: Implement on top of libcore os API.
610     }
611 
612     /**
613      * Sets the file-pointer offset, measured from the beginning of this
614      * file, at which the next read or write occurs.  The offset may be
615      * set beyond the end of the file. Setting the offset beyond the end
616      * of the file does not change the file length.  The file length will
617      * change only by writing after the offset has been set beyond the end
618      * of the file.
619      *
620      * @param      pos   the offset position, measured in bytes from the
621      *                   beginning of the file, at which to set the file
622      *                   pointer.
623      * @exception  IOException  if {@code pos} is less than
624      *                          {@code 0} or if an I/O error occurs.
625      */
seek(long pos)626     public void seek(long pos) throws IOException {
627         if (pos < 0) {
628             // Android-changed: different exception message for seek(-1).
629             // throw new IOException("Negative seek offset");
630             throw new IOException("offset < 0: " + pos);
631         } else {
632             // BEGIN Android-changed: Implement on top of libcore os API.
633             // seek0(pos);
634             try {
635                 Libcore.os.lseek(fd, pos, SEEK_SET);
636                 ioTracker.reset();
637             } catch (ErrnoException errnoException) {
638                 throw errnoException.rethrowAsIOException();
639             }
640             // END Android-changed: Implement on top of libcore os API.
641         }
642     }
643 
644     /**
645      * Returns the length of this file.
646      *
647      * @return     the length of this file, measured in bytes.
648      * @exception  IOException  if an I/O error occurs.
649      */
length()650     public long length() throws IOException {
651         // BEGIN Android-changed: Implement on top of libcore os API.
652         try {
653             return Libcore.os.fstat(fd).st_size;
654         } catch (ErrnoException errnoException) {
655             throw errnoException.rethrowAsIOException();
656         }
657         // END Android-changed: Implement on top of libcore os API.
658     }
659 
660     /**
661      * Sets the length of this file.
662      *
663      * <p> If the present length of the file as returned by the
664      * {@code length} method is greater than the {@code newLength}
665      * argument then the file will be truncated.  In this case, if the file
666      * offset as returned by the {@code getFilePointer} method is greater
667      * than {@code newLength} then after this method returns the offset
668      * will be equal to {@code newLength}.
669      *
670      * <p> If the present length of the file as returned by the
671      * {@code length} method is smaller than the {@code newLength}
672      * argument then the file will be extended.  In this case, the contents of
673      * the extended portion of the file are not defined.
674      *
675      * @param      newLength    The desired length of the file
676      * @exception  IOException  If an I/O error occurs
677      * @since      1.2
678      */
setLength(long newLength)679     public void setLength(long newLength) throws IOException {
680         // BEGIN Android-changed: Implement on top of libcore os API.
681         if (newLength < 0) {
682             throw new IllegalArgumentException("newLength < 0");
683         }
684         try {
685             Libcore.os.ftruncate(fd, newLength);
686         } catch (ErrnoException errnoException) {
687             throw errnoException.rethrowAsIOException();
688         }
689 
690         long filePointer = getFilePointer();
691         if (filePointer > newLength) {
692             seek(newLength);
693         }
694         maybeSync();
695         // END Android-changed: Implement on top of libcore os API.
696     }
697 
698 
699     /**
700      * Closes this random access file stream and releases any system
701      * resources associated with the stream. A closed random access
702      * file cannot perform input or output operations and cannot be
703      * reopened.
704      *
705      * <p> If this file has an associated channel then the channel is closed
706      * as well.
707      *
708      * @exception  IOException  if an I/O error occurs.
709      *
710      * @revised 1.4
711      * @spec JSR-51
712      */
close()713     public void close() throws IOException {
714         guard.close();
715         synchronized (closeLock) {
716             if (closed) {
717                 return;
718             }
719             closed = true;
720         }
721 
722         // BEGIN Android-changed: Implement on top of libcore os API.
723         if (channel != null && channel.isOpen()) {
724             channel.close();
725         }
726         IoBridge.closeAndSignalBlockedThreads(fd);
727         // END Android-changed: Implement on top of libcore os API.
728     }
729 
730     //
731     //  Some "reading/writing Java data types" methods stolen from
732     //  DataInputStream and DataOutputStream.
733     //
734 
735     /**
736      * Reads a {@code boolean} from this file. This method reads a
737      * single byte from the file, starting at the current file pointer.
738      * A value of {@code 0} represents
739      * {@code false}. Any other value represents {@code true}.
740      * This method blocks until the byte is read, the end of the stream
741      * is detected, or an exception is thrown.
742      *
743      * @return     the {@code boolean} value read.
744      * @exception  EOFException  if this file has reached the end.
745      * @exception  IOException   if an I/O error occurs.
746      */
readBoolean()747     public final boolean readBoolean() throws IOException {
748         int ch = this.read();
749         if (ch < 0)
750             throw new EOFException();
751         return (ch != 0);
752     }
753 
754     /**
755      * Reads a signed eight-bit value from this file. This method reads a
756      * byte from the file, starting from the current file pointer.
757      * If the byte read is {@code b}, where
758      * <code>0&nbsp;&lt;=&nbsp;b&nbsp;&lt;=&nbsp;255</code>,
759      * then the result is:
760      * <blockquote><pre>
761      *     (byte)(b)
762      * </pre></blockquote>
763      * <p>
764      * This method blocks until the byte is read, the end of the stream
765      * is detected, or an exception is thrown.
766      *
767      * @return     the next byte of this file as a signed eight-bit
768      *             {@code byte}.
769      * @exception  EOFException  if this file has reached the end.
770      * @exception  IOException   if an I/O error occurs.
771      */
readByte()772     public final byte readByte() throws IOException {
773         int ch = this.read();
774         if (ch < 0)
775             throw new EOFException();
776         return (byte)(ch);
777     }
778 
779     /**
780      * Reads an unsigned eight-bit number from this file. This method reads
781      * a byte from this file, starting at the current file pointer,
782      * and returns that byte.
783      * <p>
784      * This method blocks until the byte is read, the end of the stream
785      * is detected, or an exception is thrown.
786      *
787      * @return     the next byte of this file, interpreted as an unsigned
788      *             eight-bit number.
789      * @exception  EOFException  if this file has reached the end.
790      * @exception  IOException   if an I/O error occurs.
791      */
readUnsignedByte()792     public final int readUnsignedByte() throws IOException {
793         int ch = this.read();
794         if (ch < 0)
795             throw new EOFException();
796         return ch;
797     }
798 
799     /**
800      * Reads a signed 16-bit number from this file. The method reads two
801      * bytes from this file, starting at the current file pointer.
802      * If the two bytes read, in order, are
803      * {@code b1} and {@code b2}, where each of the two values is
804      * between {@code 0} and {@code 255}, inclusive, then the
805      * result is equal to:
806      * <blockquote><pre>
807      *     (short)((b1 &lt;&lt; 8) | b2)
808      * </pre></blockquote>
809      * <p>
810      * This method blocks until the two bytes are read, the end of the
811      * stream is detected, or an exception is thrown.
812      *
813      * @return     the next two bytes of this file, interpreted as a signed
814      *             16-bit number.
815      * @exception  EOFException  if this file reaches the end before reading
816      *               two bytes.
817      * @exception  IOException   if an I/O error occurs.
818      */
readShort()819     public final short readShort() throws IOException {
820         int ch1 = this.read();
821         int ch2 = this.read();
822         if ((ch1 | ch2) < 0)
823             throw new EOFException();
824         return (short)((ch1 << 8) + (ch2 << 0));
825     }
826 
827     /**
828      * Reads an unsigned 16-bit number from this file. This method reads
829      * two bytes from the file, starting at the current file pointer.
830      * If the bytes read, in order, are
831      * {@code b1} and {@code b2}, where
832      * <code>0&nbsp;&lt;=&nbsp;b1, b2&nbsp;&lt;=&nbsp;255</code>,
833      * then the result is equal to:
834      * <blockquote><pre>
835      *     (b1 &lt;&lt; 8) | b2
836      * </pre></blockquote>
837      * <p>
838      * This method blocks until the two bytes are read, the end of the
839      * stream is detected, or an exception is thrown.
840      *
841      * @return     the next two bytes of this file, interpreted as an unsigned
842      *             16-bit integer.
843      * @exception  EOFException  if this file reaches the end before reading
844      *               two bytes.
845      * @exception  IOException   if an I/O error occurs.
846      */
readUnsignedShort()847     public final int readUnsignedShort() throws IOException {
848         int ch1 = this.read();
849         int ch2 = this.read();
850         if ((ch1 | ch2) < 0)
851             throw new EOFException();
852         return (ch1 << 8) + (ch2 << 0);
853     }
854 
855     /**
856      * Reads a character from this file. This method reads two
857      * bytes from the file, starting at the current file pointer.
858      * If the bytes read, in order, are
859      * {@code b1} and {@code b2}, where
860      * <code>0&nbsp;&lt;=&nbsp;b1,&nbsp;b2&nbsp;&lt;=&nbsp;255</code>,
861      * then the result is equal to:
862      * <blockquote><pre>
863      *     (char)((b1 &lt;&lt; 8) | b2)
864      * </pre></blockquote>
865      * <p>
866      * This method blocks until the two bytes are read, the end of the
867      * stream is detected, or an exception is thrown.
868      *
869      * @return     the next two bytes of this file, interpreted as a
870      *                  {@code char}.
871      * @exception  EOFException  if this file reaches the end before reading
872      *               two bytes.
873      * @exception  IOException   if an I/O error occurs.
874      */
readChar()875     public final char readChar() throws IOException {
876         int ch1 = this.read();
877         int ch2 = this.read();
878         if ((ch1 | ch2) < 0)
879             throw new EOFException();
880         return (char)((ch1 << 8) + (ch2 << 0));
881     }
882 
883     /**
884      * Reads a signed 32-bit integer from this file. This method reads 4
885      * bytes from the file, starting at the current file pointer.
886      * If the bytes read, in order, are {@code b1},
887      * {@code b2}, {@code b3}, and {@code b4}, where
888      * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>,
889      * then the result is equal to:
890      * <blockquote><pre>
891      *     (b1 &lt;&lt; 24) | (b2 &lt;&lt; 16) + (b3 &lt;&lt; 8) + b4
892      * </pre></blockquote>
893      * <p>
894      * This method blocks until the four bytes are read, the end of the
895      * stream is detected, or an exception is thrown.
896      *
897      * @return     the next four bytes of this file, interpreted as an
898      *             {@code int}.
899      * @exception  EOFException  if this file reaches the end before reading
900      *               four bytes.
901      * @exception  IOException   if an I/O error occurs.
902      */
readInt()903     public final int readInt() throws IOException {
904         int ch1 = this.read();
905         int ch2 = this.read();
906         int ch3 = this.read();
907         int ch4 = this.read();
908         if ((ch1 | ch2 | ch3 | ch4) < 0)
909             throw new EOFException();
910         return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
911     }
912 
913     /**
914      * Reads a signed 64-bit integer from this file. This method reads eight
915      * bytes from the file, starting at the current file pointer.
916      * If the bytes read, in order, are
917      * {@code b1}, {@code b2}, {@code b3},
918      * {@code b4}, {@code b5}, {@code b6},
919      * {@code b7}, and {@code b8,} where:
920      * <blockquote><pre>
921      *     0 &lt;= b1, b2, b3, b4, b5, b6, b7, b8 &lt;=255,
922      * </pre></blockquote>
923      * <p>
924      * then the result is equal to:
925      * <blockquote><pre>
926      *     ((long)b1 &lt;&lt; 56) + ((long)b2 &lt;&lt; 48)
927      *     + ((long)b3 &lt;&lt; 40) + ((long)b4 &lt;&lt; 32)
928      *     + ((long)b5 &lt;&lt; 24) + ((long)b6 &lt;&lt; 16)
929      *     + ((long)b7 &lt;&lt; 8) + b8
930      * </pre></blockquote>
931      * <p>
932      * This method blocks until the eight bytes are read, the end of the
933      * stream is detected, or an exception is thrown.
934      *
935      * @return     the next eight bytes of this file, interpreted as a
936      *             {@code long}.
937      * @exception  EOFException  if this file reaches the end before reading
938      *               eight bytes.
939      * @exception  IOException   if an I/O error occurs.
940      */
readLong()941     public final long readLong() throws IOException {
942         return ((long)(readInt()) << 32) + (readInt() & 0xFFFFFFFFL);
943     }
944 
945     /**
946      * Reads a {@code float} from this file. This method reads an
947      * {@code int} value, starting at the current file pointer,
948      * as if by the {@code readInt} method
949      * and then converts that {@code int} to a {@code float}
950      * using the {@code intBitsToFloat} method in class
951      * {@code Float}.
952      * <p>
953      * This method blocks until the four bytes are read, the end of the
954      * stream is detected, or an exception is thrown.
955      *
956      * @return     the next four bytes of this file, interpreted as a
957      *             {@code float}.
958      * @exception  EOFException  if this file reaches the end before reading
959      *             four bytes.
960      * @exception  IOException   if an I/O error occurs.
961      * @see        java.io.RandomAccessFile#readInt()
962      * @see        java.lang.Float#intBitsToFloat(int)
963      */
readFloat()964     public final float readFloat() throws IOException {
965         return Float.intBitsToFloat(readInt());
966     }
967 
968     /**
969      * Reads a {@code double} from this file. This method reads a
970      * {@code long} value, starting at the current file pointer,
971      * as if by the {@code readLong} method
972      * and then converts that {@code long} to a {@code double}
973      * using the {@code longBitsToDouble} method in
974      * class {@code Double}.
975      * <p>
976      * This method blocks until the eight bytes are read, the end of the
977      * stream is detected, or an exception is thrown.
978      *
979      * @return     the next eight bytes of this file, interpreted as a
980      *             {@code double}.
981      * @exception  EOFException  if this file reaches the end before reading
982      *             eight bytes.
983      * @exception  IOException   if an I/O error occurs.
984      * @see        java.io.RandomAccessFile#readLong()
985      * @see        java.lang.Double#longBitsToDouble(long)
986      */
readDouble()987     public final double readDouble() throws IOException {
988         return Double.longBitsToDouble(readLong());
989     }
990 
991     /**
992      * Reads the next line of text from this file.  This method successively
993      * reads bytes from the file, starting at the current file pointer,
994      * until it reaches a line terminator or the end
995      * of the file.  Each byte is converted into a character by taking the
996      * byte's value for the lower eight bits of the character and setting the
997      * high eight bits of the character to zero.  This method does not,
998      * therefore, support the full Unicode character set.
999      *
1000      * <p> A line of text is terminated by a carriage-return character
1001      * ({@code '\u005Cr'}), a newline character ({@code '\u005Cn'}), a
1002      * carriage-return character immediately followed by a newline character,
1003      * or the end of the file.  Line-terminating characters are discarded and
1004      * are not included as part of the string returned.
1005      *
1006      * <p> This method blocks until a newline character is read, a carriage
1007      * return and the byte following it are read (to see if it is a newline),
1008      * the end of the file is reached, or an exception is thrown.
1009      *
1010      * @return     the next line of text from this file, or null if end
1011      *             of file is encountered before even one byte is read.
1012      * @exception  IOException  if an I/O error occurs.
1013      */
1014 
readLine()1015     public final String readLine() throws IOException {
1016         StringBuffer input = new StringBuffer();
1017         int c = -1;
1018         boolean eol = false;
1019 
1020         while (!eol) {
1021             switch (c = read()) {
1022             case -1:
1023             case '\n':
1024                 eol = true;
1025                 break;
1026             case '\r':
1027                 eol = true;
1028                 long cur = getFilePointer();
1029                 if ((read()) != '\n') {
1030                     seek(cur);
1031                 }
1032                 break;
1033             default:
1034                 input.append((char)c);
1035                 break;
1036             }
1037         }
1038 
1039         if ((c == -1) && (input.length() == 0)) {
1040             return null;
1041         }
1042         return input.toString();
1043     }
1044 
1045     /**
1046      * Reads in a string from this file. The string has been encoded
1047      * using a
1048      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
1049      * format.
1050      * <p>
1051      * The first two bytes are read, starting from the current file
1052      * pointer, as if by
1053      * {@code readUnsignedShort}. This value gives the number of
1054      * following bytes that are in the encoded string, not
1055      * the length of the resulting string. The following bytes are then
1056      * interpreted as bytes encoding characters in the modified UTF-8 format
1057      * and are converted into characters.
1058      * <p>
1059      * This method blocks until all the bytes are read, the end of the
1060      * stream is detected, or an exception is thrown.
1061      *
1062      * @return     a Unicode string.
1063      * @exception  EOFException            if this file reaches the end before
1064      *               reading all the bytes.
1065      * @exception  IOException             if an I/O error occurs.
1066      * @exception  UTFDataFormatException  if the bytes do not represent
1067      *               valid modified UTF-8 encoding of a Unicode string.
1068      * @see        java.io.RandomAccessFile#readUnsignedShort()
1069      */
readUTF()1070     public final String readUTF() throws IOException {
1071         return DataInputStream.readUTF(this);
1072     }
1073 
1074     /**
1075      * Writes a {@code boolean} to the file as a one-byte value. The
1076      * value {@code true} is written out as the value
1077      * {@code (byte)1}; the value {@code false} is written out
1078      * as the value {@code (byte)0}. The write starts at
1079      * the current position of the file pointer.
1080      *
1081      * @param      v   a {@code boolean} value to be written.
1082      * @exception  IOException  if an I/O error occurs.
1083      */
writeBoolean(boolean v)1084     public final void writeBoolean(boolean v) throws IOException {
1085         write(v ? 1 : 0);
1086         //written++;
1087     }
1088 
1089     /**
1090      * Writes a {@code byte} to the file as a one-byte value. The
1091      * write starts at the current position of the file pointer.
1092      *
1093      * @param      v   a {@code byte} value to be written.
1094      * @exception  IOException  if an I/O error occurs.
1095      */
writeByte(int v)1096     public final void writeByte(int v) throws IOException {
1097         write(v);
1098         //written++;
1099     }
1100 
1101     /**
1102      * Writes a {@code short} to the file as two bytes, high byte first.
1103      * The write starts at the current position of the file pointer.
1104      *
1105      * @param      v   a {@code short} to be written.
1106      * @exception  IOException  if an I/O error occurs.
1107      */
writeShort(int v)1108     public final void writeShort(int v) throws IOException {
1109         write((v >>> 8) & 0xFF);
1110         write((v >>> 0) & 0xFF);
1111         //written += 2;
1112     }
1113 
1114     /**
1115      * Writes a {@code char} to the file as a two-byte value, high
1116      * byte first. The write starts at the current position of the
1117      * file pointer.
1118      *
1119      * @param      v   a {@code char} value to be written.
1120      * @exception  IOException  if an I/O error occurs.
1121      */
writeChar(int v)1122     public final void writeChar(int v) throws IOException {
1123         write((v >>> 8) & 0xFF);
1124         write((v >>> 0) & 0xFF);
1125         //written += 2;
1126     }
1127 
1128     /**
1129      * Writes an {@code int} to the file as four bytes, high byte first.
1130      * The write starts at the current position of the file pointer.
1131      *
1132      * @param      v   an {@code int} to be written.
1133      * @exception  IOException  if an I/O error occurs.
1134      */
writeInt(int v)1135     public final void writeInt(int v) throws IOException {
1136         write((v >>> 24) & 0xFF);
1137         write((v >>> 16) & 0xFF);
1138         write((v >>>  8) & 0xFF);
1139         write((v >>>  0) & 0xFF);
1140         //written += 4;
1141     }
1142 
1143     /**
1144      * Writes a {@code long} to the file as eight bytes, high byte first.
1145      * The write starts at the current position of the file pointer.
1146      *
1147      * @param      v   a {@code long} to be written.
1148      * @exception  IOException  if an I/O error occurs.
1149      */
writeLong(long v)1150     public final void writeLong(long v) throws IOException {
1151         write((int)(v >>> 56) & 0xFF);
1152         write((int)(v >>> 48) & 0xFF);
1153         write((int)(v >>> 40) & 0xFF);
1154         write((int)(v >>> 32) & 0xFF);
1155         write((int)(v >>> 24) & 0xFF);
1156         write((int)(v >>> 16) & 0xFF);
1157         write((int)(v >>>  8) & 0xFF);
1158         write((int)(v >>>  0) & 0xFF);
1159         //written += 8;
1160     }
1161 
1162     /**
1163      * Converts the float argument to an {@code int} using the
1164      * {@code floatToIntBits} method in class {@code Float},
1165      * and then writes that {@code int} value to the file as a
1166      * four-byte quantity, high byte first. The write starts at the
1167      * current position of the file pointer.
1168      *
1169      * @param      v   a {@code float} value to be written.
1170      * @exception  IOException  if an I/O error occurs.
1171      * @see        java.lang.Float#floatToIntBits(float)
1172      */
writeFloat(float v)1173     public final void writeFloat(float v) throws IOException {
1174         writeInt(Float.floatToIntBits(v));
1175     }
1176 
1177     /**
1178      * Converts the double argument to a {@code long} using the
1179      * {@code doubleToLongBits} method in class {@code Double},
1180      * and then writes that {@code long} value to the file as an
1181      * eight-byte quantity, high byte first. The write starts at the current
1182      * position of the file pointer.
1183      *
1184      * @param      v   a {@code double} value to be written.
1185      * @exception  IOException  if an I/O error occurs.
1186      * @see        java.lang.Double#doubleToLongBits(double)
1187      */
writeDouble(double v)1188     public final void writeDouble(double v) throws IOException {
1189         writeLong(Double.doubleToLongBits(v));
1190     }
1191 
1192     /**
1193      * Writes the string to the file as a sequence of bytes. Each
1194      * character in the string is written out, in sequence, by discarding
1195      * its high eight bits. The write starts at the current position of
1196      * the file pointer.
1197      *
1198      * @param      s   a string of bytes to be written.
1199      * @exception  IOException  if an I/O error occurs.
1200      */
1201     @SuppressWarnings("deprecation")
writeBytes(String s)1202     public final void writeBytes(String s) throws IOException {
1203         int len = s.length();
1204         byte[] b = new byte[len];
1205         s.getBytes(0, len, b, 0);
1206         writeBytes(b, 0, len);
1207     }
1208 
1209     /**
1210      * Writes a string to the file as a sequence of characters. Each
1211      * character is written to the data output stream as if by the
1212      * {@code writeChar} method. The write starts at the current
1213      * position of the file pointer.
1214      *
1215      * @param      s   a {@code String} value to be written.
1216      * @exception  IOException  if an I/O error occurs.
1217      * @see        java.io.RandomAccessFile#writeChar(int)
1218      */
writeChars(String s)1219     public final void writeChars(String s) throws IOException {
1220         int clen = s.length();
1221         int blen = 2*clen;
1222         byte[] b = new byte[blen];
1223         char[] c = new char[clen];
1224         s.getChars(0, clen, c, 0);
1225         for (int i = 0, j = 0; i < clen; i++) {
1226             b[j++] = (byte)(c[i] >>> 8);
1227             b[j++] = (byte)(c[i] >>> 0);
1228         }
1229         writeBytes(b, 0, blen);
1230     }
1231 
1232     /**
1233      * Writes a string to the file using
1234      * <a href="DataInput.html#modified-utf-8">modified UTF-8</a>
1235      * encoding in a machine-independent manner.
1236      * <p>
1237      * First, two bytes are written to the file, starting at the
1238      * current file pointer, as if by the
1239      * {@code writeShort} method giving the number of bytes to
1240      * follow. This value is the number of bytes actually written out,
1241      * not the length of the string. Following the length, each character
1242      * of the string is output, in sequence, using the modified UTF-8 encoding
1243      * for each character.
1244      *
1245      * @param      str   a string to be written.
1246      * @exception  IOException  if an I/O error occurs.
1247      */
writeUTF(String str)1248     public final void writeUTF(String str) throws IOException {
1249         DataOutputStream.writeUTF(str, this);
1250     }
1251 
1252     // Android-added: use finalize() to detect if not close()d.
finalize()1253     @Override protected void finalize() throws Throwable {
1254         try {
1255             if (guard != null) {
1256                 guard.warnIfOpen();
1257             }
1258             close();
1259         } finally {
1260             super.finalize();
1261         }
1262     }
1263 }
1264