001: /* Licensed to the Apache Software Foundation (ASF) under one or more
002: * contributor license agreements. See the NOTICE file distributed with
003: * this work for additional information regarding copyright ownership.
004: * The ASF licenses this file to You under the Apache License, Version 2.0
005: * (the "License"); you may not use this file except in compliance with
006: * the License. You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package java.nio.channels;
018:
019: import java.io.IOException;
020: import java.nio.ByteBuffer;
021: import java.nio.MappedByteBuffer;
022: import java.nio.channels.spi.AbstractInterruptibleChannel;
023:
024: /**
025: * An abstract channel type for interaction with a platform file.
026: * <p>
027: * A FileChannel defines the methods for reading, writing, memory mapping, and
028: * manipulating the logical state of a platform file. This type does not have a
029: * method for opening files, since this behaviour has been delegated to the
030: * <code>FileInputStream</code>, <code>FileOutputStream</code>, and
031: * <code>RandomAccessFile</code> types.
032: * </p>
033: * <p>
034: * FileChannels created from a FileInputStream, or a RandomAccessFile created in
035: * mode "r", are read-only. FileChannels created from a FileOutputStream are
036: * write-only. FileChannels created from a RandomAccessFile created in mode "rw"
037: * are read/write. FileChannels created from a RandomAccessFile that was opened
038: * in append-mode will also be in append-mode -- meaning that each write will be
039: * proceeded by a seek to the end of file. Some platforms will seek and write
040: * atomically, others will not.
041: * </p>
042: * <p>
043: * FileChannels has a virtual pointer into the file which is referred to as a
044: * file <em>position</em>. The position can be manipulated by repositioning
045: * it within the file, and its current position can be queried.
046: * </p>
047: * <p>
048: * FileChannels also have an associated <em>size</em>. The size of the file
049: * is the number of bytes that it currently contains. The size can be
050: * manipulated by adding more bytes to the end of the file (which increases the
051: * size) or truncating the file (which decreases the size). The current size can
052: * also be queried.
053: * </p>
054: * <p>
055: * FileChannels have operations beyond the simple read, write, and close. They
056: * can also:
057: * <ul>
058: * <li>request that cached data be forced onto the disk</li>
059: * <li>lock ranges of bytes associated with the file</li>
060: * <li>transfer data directly to another channel in a manner that has the
061: * potential to be optimized by the platform</li>
062: * <li>memory-mapping files into NIO buffers to provide efficient manipulation
063: * of file data</li>
064: * <li>read and write to the file at absolute byte offsets in a fashion that
065: * does not modify the current position</li>
066: * </ul>
067: * </p>
068: * <p>
069: * FileChannels are thread-safe. Only one operation involving manipulation of
070: * the file position may be in-flight at once. Subsequent calls to such
071: * operations will block, and one of those blocked will be freed to continue
072: * when the first operation has completed. There is no ordered queue or fairness
073: * applied to the blocked threads.
074: * </p>
075: * <p>
076: * It is undefined whether operations that do not manipulate the file position
077: * will also block when there are any other operations in-flight.
078: * </p>
079: * <p>
080: * The logical view of the underlying file is consistent across all FileChannels
081: * and IO streams opened on the same file by the same JVM process. Therefore
082: * modifications performed via a channel will be visible to the stream, and vice
083: * versa; including modifications to the file position, content, size, etc.
084: * </p>
085: */
086: public abstract class FileChannel extends AbstractInterruptibleChannel
087: implements GatheringByteChannel, ScatteringByteChannel,
088: ByteChannel {
089:
090: /**
091: * A type of file mapping modes.
092: */
093: public static class MapMode {
094: /**
095: * Private mapping mode (equivalent to copy on write).
096: */
097: public static final MapMode PRIVATE = new MapMode("PRIVATE"); //$NON-NLS-1$
098:
099: /**
100: * Read-only mapping mode.
101: */
102: public static final MapMode READ_ONLY = new MapMode("READ_ONLY"); //$NON-NLS-1$
103:
104: /**
105: * Read-write mapping mode.
106: */
107: public static final MapMode READ_WRITE = new MapMode(
108: "READ_WRITE"); //$NON-NLS-1$
109:
110: // The string used to display the mapping mode.
111: private final String displayName;
112:
113: /*
114: * Private constructor prevents others creating new modes.
115: */
116: private MapMode(String displayName) {
117: super ();
118: this .displayName = displayName;
119: }
120:
121: /**
122: * Answers a string version of the mapping mode useful for debugging
123: * etc.
124: *
125: * @return the mode string.
126: */
127: @Override
128: public String toString() {
129: return displayName;
130: }
131: }
132:
133: /**
134: * Protected default constructor.
135: */
136: protected FileChannel() {
137: super ();
138: }
139:
140: /**
141: * Request that all updates to the channel are committed to the storage
142: * device.
143: * <p>
144: * When this method returns all modifications made to the platform file
145: * underlying this channel will be committed to a local storage device. If
146: * the file is not hosted locally, such as a networked file system, then
147: * applications cannot be certain that the modifications have been
148: * committed.
149: * </p>
150: * <p>
151: * There are no assurances given that changes made to the file using methods
152: * defined elsewhere will be committed. For example, changes made via a
153: * mapped byte buffer may not be committed.
154: * </p>
155: * <p>
156: * The <code>metadata</code> parameter indicated whether the update should
157: * include the file's metadata such as last modification time, last access
158: * time, etc. Note that passing <code>true</code> may invoke an underlying
159: * write to the operating system (if the platform is maintaining metadata
160: * such as last access time), even if the channel is opened read-only.
161: *
162: * @param metadata
163: * true if the file metadata should be flushed in addition to the
164: * file content, and false otherwise.
165: * @throws ClosedChannelException
166: * if the channel is already closed.
167: * @throws IOException
168: * some other problem occurred.
169: */
170: public abstract void force(boolean metadata) throws IOException;
171:
172: /**
173: * Obtain an exclusive lock on this file.
174: * <p>
175: * This is a convenience method for acquiring a maximum length lock on a
176: * file. It is equivalent to:
177: *
178: * <pre>
179: * fileChannel.lock(0L, Long.MAX_VALUE, false)
180: * </pre>
181: *
182: * @return the lock object representing the locked file area.
183: * @throws ClosedChannelException
184: * the file channel is closed.
185: * @throws NonWritableChannelException
186: * this channel was not opened for writing.
187: * @throws OverlappingFileLockException
188: * Either a lock is already held that overlaps this lock
189: * request, or another thread is waiting to acquire a lock that
190: * will overlap with this request.
191: * @throws FileLockInterruptionException
192: * The calling thread was interrupted while waiting to acquire
193: * the lock.
194: * @throws AsynchronousCloseException
195: * The channel was closed while the calling thread was waiting
196: * to acquire the lock.
197: * @throws IOException
198: * some other problem occurred obtaining the requested lock.
199: */
200: public final FileLock lock() throws IOException {
201: return lock(0L, Long.MAX_VALUE, false);
202: }
203:
204: /**
205: * Obtain a lock on a specified region of the file.
206: * <p>
207: * This is the blocking version of lock acquisition, see also the
208: * <code>tryLock()</code> methods.
209: * </p>
210: * <p>
211: * Attempts to acquire an overlapping lock region will fail. The attempt
212: * will fail if the overlapping lock has already been obtained, or if
213: * another thread is currently waiting to acquire the overlapping lock.
214: * </p>
215: * <p>
216: * If the request is not for an overlapping lock, the thread calling this
217: * method will block until the lock is obtained (likely by no contention or
218: * another process releasing a lock), or this thread being interrupted or
219: * the channel closed.
220: * </p>
221: * <p>
222: * If the lock is obtained successfully then the FileLock object returned
223: * represents the lock for subsequent operations on the locked region.
224: * </p>
225: * <p>
226: * If the thread is interrupted while waiting for the lock, the thread is
227: * set to the interrupted state, and throws a
228: * <code>FileLockInterruptionException</code>. If the channel is closed
229: * while the thread is waiting to obtain the lock then the thread throws a
230: * <code>AsynchronousCloseException</code>.
231: * </p>
232: * <p>
233: * There is no requirement for the position and size to be within the
234: * current start and length of the file.
235: * </p>
236: * <p>
237: * Some platforms do not support shared locks, and if a request is made for
238: * a shared lock on such a platform this method will attempt to acquire an
239: * exclusive lock instead. It is undefined whether the lock obtained is
240: * advisory or mandatory.
241: * </p>
242: *
243: * @param position
244: * the starting position for the lock region
245: * @param size
246: * the length of the lock, in bytes
247: * @param shared
248: * a flag indicating whether an attempt should be made to acquire
249: * a shared lock.
250: * @return the file lock object
251: * @throws IllegalArgumentException
252: * if the parameters are invalid.
253: * @throws ClosedChannelException
254: * if the channel is already closed.
255: * @throws OverlappingFileLockException
256: * if the requested region overlaps an existing lock or pending
257: * lock request.
258: * @throws NonReadableChannelException
259: * if the channel is not open in read-mode and shared is true.
260: * @throws NonWritableChannelException
261: * if the channel is not open in write mode and shared is false.
262: * @throws AsynchronousCloseException
263: * if the channel is closed by another thread while this method
264: * is in operation.
265: * @throws FileLockInterruptionException
266: * if the thread is interrupted while in the state of waiting on
267: * the desired file lock.
268: * @throws IOException
269: * if some other IO problem occurs.
270: */
271: public abstract FileLock lock(long position, long size,
272: boolean shared) throws IOException;
273:
274: /**
275: * Maps the file into memory.There can be three modes:Read-only,Read/write
276: * and Private.
277: *
278: * After mapping, the memory and the file channel do not affect each other.
279: *
280: * Note : mapping a file into memory is usually expensive.
281: *
282: * @param mode
283: * one of three modes to map
284: * @param position
285: * the starting position of the file
286: * @param size
287: * the size to map
288: * @return the mapped byte buffer
289: *
290: * @throws NonReadableChannelException
291: * If the file is not opened for reading but the given mode is
292: * "READ_ONLY"
293: * @throws NonWritableChannelException
294: * If the file is not opened for writing but the mode is not
295: * "READ_ONLY"
296: * @throws IllegalArgumentException
297: * If the given parameters of position and size are not correct
298: * @throws IOException
299: * If any I/O error occurs
300: */
301: public abstract MappedByteBuffer map(FileChannel.MapMode mode,
302: long position, long size) throws IOException;
303:
304: /**
305: * Answers the current value of the file position pointer.
306: *
307: * @return the current position as a positive integer number of bytes from
308: * the start of the file.
309: * @throws ClosedChannelException
310: * if the channel is already closed.
311: * @throws IOException
312: * if some other IO problem occurs.
313: */
314: public abstract long position() throws IOException;
315:
316: /**
317: * Sets the file position pointer to a new value.
318: * <p>
319: * The argument is the number of bytes counted from the start of the file.
320: * The position cannot be set to a value that is negative. The new position
321: * can be set beyond the current file size. If set beyond the current file
322: * size, attempts to read will return end of file, and writes will succeed,
323: * but fill-in the bytes between the current end of file and the position
324: * with the required number of (unspecified) byte values.
325: *
326: * @param offset
327: * the new file position, in bytes.
328: * @return the receiver.
329: * @throws IllegalArgumentException
330: * if the new position is negative.
331: * @throws ClosedChannelException
332: * if the channel is already closed.
333: * @throws IOException
334: * if some other IO problem occurs.
335: */
336: public abstract FileChannel position(long offset)
337: throws IOException;
338:
339: /**
340: * Reads bytes from the channel into the given byte buffer.
341: * <p>
342: * The bytes are read starting at the current file position, and after some
343: * number of bytes are read (up to the remaining number of bytes in the
344: * buffer) the file position is increased by the number of bytes actually
345: * read.
346: *
347: * @see java.nio.channels.ReadableByteChannel#read(java.nio.ByteBuffer)
348: */
349: public abstract int read(ByteBuffer buffer) throws IOException;
350:
351: /**
352: * Reads bytes from the file channel into the given buffer starting from the
353: * given file position.
354: * <p>
355: * The bytes are read starting at the given file position (up to the
356: * remaining number of bytes in the buffer). The number of bytes actually
357: * read is returned.
358: * </p>
359: * <p>
360: * If the position is beyond the current end of file, then no bytes are
361: * read.
362: * </p>
363: * <p>
364: * Note that file position is unmodified by this method.
365: * </p>
366: *
367: * @param buffer
368: * the buffer to receive the bytes
369: * @param position
370: * the (non-negative) position at which to read the bytes.
371: * @return the number of bytes actually read.
372: * @throws IllegalArgumentException
373: * if <code>position</code> is less than <code>-1</code>.
374: * @throws ClosedChannelException
375: * if the channel is already closed.
376: * @throws NonReadableChannelException
377: * if the channel was not opened in read-mode.
378: * @throws AsynchronousCloseException
379: * if the channel is closed by another thread while this method
380: * is in operation.
381: * @throws ClosedByInterruptException
382: * if another thread interrupts the calling thread while the
383: * operation is in progress. The calling thread will have the
384: * interrupt state set, and the channel will be closed.
385: * @throws IOException
386: * some other IO error occurred.
387: */
388: public abstract int read(ByteBuffer buffer, long position)
389: throws IOException;
390:
391: /**
392: * Reads bytes from the channel into all the given byte buffers.
393: * <p>
394: * The bytes are read starting at the current file position, and after some
395: * number of bytes are read (up to the remaining number of bytes in all the
396: * buffers) the file position is increased by the number of bytes actually
397: * read.
398: * </p>
399: * <p>
400: * This method behaves exactly like:
401: *
402: * <pre>
403: * read(buffers, 0, buffers.length);
404: * </pre>
405: *
406: * </p>
407: *
408: * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[])
409: */
410: public final long read(ByteBuffer[] buffers) throws IOException {
411: return read(buffers, 0, buffers.length);
412: }
413:
414: /**
415: * Reads bytes from the file channel into a subset of the given byte
416: * buffers.
417: *
418: * @see java.nio.channels.ScatteringByteChannel#read(java.nio.ByteBuffer[],
419: * int, int)
420: */
421: public abstract long read(ByteBuffer[] buffers, int start,
422: int number) throws IOException;
423:
424: /**
425: * Answers the size of the file underlying this channel, in bytes.
426: *
427: * @return the size of the file in bytes.
428: * @throws ClosedChannelException
429: * if the channel is closed.
430: * @throws IOException
431: * if a problem occurs getting the size of the file.
432: */
433: public abstract long size() throws IOException;
434:
435: /**
436: * Transfers bytes into this channel's file from the given readable byte
437: * channel. It may be very efficient.
438: *
439: * By invoking this method, it will read form the source channel and write
440: * into the file channel.
441: *
442: * Note: no guarantee whether all bytes may be transferred. And it does not
443: * modify the position of the channel.
444: *
445: * @param src
446: * the source channel to read
447: * @param position
448: * the non-negative position to begin
449: * @param count
450: * the non-negative bytes to be transferred
451: * @return the number of bytes that are transferred.
452: *
453: * @throws IllegalArgumentException
454: * If the parameters are not correct
455: * @throws NonReadableChannelException
456: * If the source channel is not readable
457: * @throws NonWritableChannelException
458: * If this channel is not writable
459: * @throws ClosedChannelException
460: * If either channel has already been closed
461: * @throws AsynchronousCloseException
462: * If either channel is closed by other threads during this
463: * operation
464: * @throws ClosedByInterruptException
465: * If the thread is interrupted during this operation
466: * @throws IOException
467: * If any I/O error occurs
468: */
469: public abstract long transferFrom(ReadableByteChannel src,
470: long position, long count) throws IOException;
471:
472: /**
473: * Transfers data from the file to the given channel. It may be very
474: * efficient.
475: *
476: * By invoking this method, it will read form the file and write into the
477: * writable channel.
478: *
479: * Note: no guarantee whether all bytes may be transfered.And it does not
480: * modify the position of the channel.
481: *
482: * @param position
483: * the non-negative position to begin
484: * @param count
485: * the non-negative bytes to be transferred
486: * @param target
487: * the target channel to write into
488: * @return the number of bytes that were transferred.
489: *
490: * @throws IllegalArgumentException
491: * If the parameters are not correct
492: * @throws NonReadableChannelException
493: * If this channel is not readable
494: * @throws NonWritableChannelException
495: * If the target channel is not writable
496: * @throws ClosedChannelException
497: * If either channel has already been closed
498: * @throws AsynchronousCloseException
499: * If either channel is closed by other threads during this
500: * operation
501: * @throws ClosedByInterruptException
502: * If the thread is interrupted during this operation
503: * @throws IOException
504: * If any I/O error occurs
505: */
506: public abstract long transferTo(long position, long count,
507: WritableByteChannel target) throws IOException;
508:
509: /**
510: * Truncates the file underlying this channel to a given size.
511: * <p>
512: * Any bytes beyond the given size are removed from the file. If there are
513: * no bytes beyond the given size then the file contents are unmodified.
514: * </p>
515: * <p>
516: * If the file position is currently greater than the given size, then it is
517: * set to be the given size.
518: * </p>
519: *
520: * @param size
521: * the maximum size of the underlying file
522: * @throws IllegalArgumentException
523: * the requested size is negative.
524: * @throws ClosedChannelException
525: * the channel is closed.
526: * @throws NonWritableChannelException
527: * the channel cannot be written.
528: * @throws IOException
529: * some other IO problem occurred.
530: * @return this channel
531: */
532: public abstract FileChannel truncate(long size) throws IOException;
533:
534: /**
535: * Attempts to acquire an exclusive lock on this file without blocking.
536: * <p>
537: * This is a convenience method for attempting to acquire a maximum length
538: * lock on the file. It is equivalent to:
539: *
540: * <pre>
541: * fileChannel.tryLock(0L, Long.MAX_VALUE, false)
542: * </pre>
543: *
544: * </p>
545: * <p>
546: * The method returns <code>null</code> if the acquisition would result in
547: * an overlapped lock with another OS process.
548: * </p>
549: *
550: * @return the file lock object, or <code>null</code> if the lock would
551: * overlap an existing exclusive lock in another OS process.
552: * @throws ClosedChannelException
553: * the file channel is closed.
554: * @throws OverlappingFileLockException
555: * Either a lock is already held that overlaps this lock
556: * request, or another thread is waiting to acquire a lock that
557: * will overlap with this request.
558: * @throws IOException
559: * if any I/O error occurs
560: */
561: public final FileLock tryLock() throws IOException {
562: return tryLock(0L, Long.MAX_VALUE, false);
563: }
564:
565: /**
566: * Attempts to acquire an exclusive lock on this file without blocking.
567: * <p>
568: * The method returns <code>null</code> if the acquisition would result in
569: * an overlapped lock with another OS process.
570: * </p>
571: *
572: * @param position
573: * the starting position
574: * @param size
575: * the size of file to lock
576: * @param shared
577: * true if share
578: * @return the file lock object, or <code>null</code> if the lock would
579: * overlap an existing exclusive lock in another OS process.
580: *
581: * @throws IllegalArgumentException
582: * If any parameters are bad
583: * @throws ClosedChannelException
584: * the file channel is closed.
585: * @throws OverlappingFileLockException
586: * Either a lock is already held that overlaps this lock
587: * request, or another thread is waiting to acquire a lock that
588: * will overlap with this request.
589: * @throws IOException
590: * if any I/O error occurs
591: */
592: public abstract FileLock tryLock(long position, long size,
593: boolean shared) throws IOException;
594:
595: /**
596: * Writes bytes from the given byte buffer into the file channel.
597: * <p>
598: * The bytes are written starting at the current file position, and after
599: * some number of bytes are written (up to the remaining number of bytes in
600: * the buffer) the file position is increased by the number of bytes
601: * actually written.
602: *
603: * @see java.nio.channels.WritableByteChannel#write(java.nio.ByteBuffer)
604: *
605: * @param src
606: * the source buffer to write
607: */
608: public abstract int write(ByteBuffer src) throws IOException;
609:
610: /**
611: * Writes bytes from the given buffer to the file channel starting at the
612: * given file position.
613: * <p>
614: * The bytes are written starting at the given file position (up to the
615: * remaining number of bytes in the buffer). The number of bytes actually
616: * written is returned.
617: * </p>
618: * <p>
619: * If the position is beyond the current end of file, then the file is first
620: * extended up to the given position by the required number of unspecified
621: * byte values.
622: * </p>
623: * <p>
624: * Note that file position is unmodified by this method.
625: * </p>
626: *
627: * @param buffer
628: * the buffer containing the bytes to be written.
629: * @param position
630: * the (non-negative) position at which to write the bytes.
631: * @return the number of bytes actually written.
632: * @throws IllegalArgumentException
633: * if <code>position</code> is less than <code>-1</code>.
634: * @throws ClosedChannelException
635: * if the channel is already closed.
636: * @throws NonWritableChannelException
637: * if the channel was not opened in write-mode.
638: * @throws AsynchronousCloseException
639: * if the channel is closed by another thread while this method
640: * is in operation.
641: * @throws ClosedByInterruptException
642: * if another thread interrupts the calling thread while the
643: * operation is in progress. The calling thread will have the
644: * interrupt state set, and the channel will be closed.
645: * @throws IOException
646: * some other IO error occurred.
647: */
648: public abstract int write(ByteBuffer buffer, long position)
649: throws IOException;
650:
651: /**
652: * Writes bytes from all the given byte buffers into the file channel.
653: * <p>
654: * The bytes are written starting at the current file position, and after
655: * some number of bytes are written (up to the remaining number of bytes in
656: * all the buffers) the file position is increased by the number of bytes
657: * actually written.
658: * <p>
659: * This method behaves exactly like:
660: *
661: * <pre>
662: * write(buffers, 0, buffers.length);
663: * </pre>
664: *
665: * </p>
666: *
667: * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[])
668: */
669: public final long write(ByteBuffer[] buffers) throws IOException {
670: return write(buffers, 0, buffers.length);
671: }
672:
673: /**
674: * @see java.nio.channels.GatheringByteChannel#write(java.nio.ByteBuffer[],
675: * int, int)
676: */
677: public abstract long write(ByteBuffer[] buffers, int offset,
678: int length) throws IOException;
679: }
|