目錄
簡介
構造函數,字段NO_ATTRIBUTES,方法2個open,3個read,3個write
方法2個position,size,truncate,force,transferTo,transferFrom,read,write
内部類MapMode
方法map,2個lock,2個tryLock
簡介
package java.nio.channels;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.nio.file.*;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.spi.*;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
/**
* 用于讀取、寫入、映射和操作檔案的通道。
*
* <p> 檔案通道是連接配接到檔案的可查找位元組通道。
* 它在檔案中有一個目前位置,可以查詢和修改。
* 檔案本身包含一個可變長度的位元組序列,這些位元組可以讀寫,并且可以查詢其目前大小。
* 當寫入的位元組超過目前大小時,檔案的大小會增加;
* 當檔案被截斷時,檔案的大小會減小。
* 該檔案還可能有一些相關的中繼資料,如通路權限、内容類型和上次修改時間;
* 此類不定義中繼資料通路的方法。
*
* <p> 除了類似的位元組通道的讀、寫和關閉操作外,此類還定義了以下特定于檔案的操作:</p>
*
* <ul>
*
* <li><p> 可以在檔案的絕對位置以不影響信道目前位置的方式
* 讀取read(ByteBuffer, long)或寫入write(ByteBuffer, long)位元組。</p></li>
*
* <li><p> 檔案的一個區域可以直接映射到記憶體中;
* 對于大檔案,這通常比調用通常的讀或寫方法更有效。
* </p></li>
*
* <li><p> 對檔案所做的更新可以強制到底層儲存設備,以確定在系統崩潰時資料不會丢失。</p></li>
*
* <li><p> 位元組可以從一個檔案傳輸到另一個通道,
* 并且可以通過許多作業系統優化的方式,直接傳輸到檔案系統緩存或直接從檔案系統緩存傳輸。
* </p></li>
*
* <li><p> 檔案的一個區域可能被鎖定,不允許其他程式通路。 </p></li>
*
* </ul>
*
* <p> 多個并發線程可以安全地使用檔案通道。
* close方法可以在任何時候調用,正如Channel接口指定的那樣。
* 在任何給定的時間内,隻有一個涉及通道位置或可以更改其檔案大小的操作正在進行;
* 嘗試啟動第二個此類操作,而正在進行的第一個操作,第二個操作将被阻止,直到第一個操作完成。
* 其他操作,特别是那些采取明确position的操作,可能同時進行;
* 它們是否真的這樣做取決于底層實作,是以未作說明。
*
* <p> 此類執行個體提供的檔案視圖被保證與同一程式中其他執行個體提供的同一檔案的其他視圖一緻。
* 但是,由于底層作業系統執行的緩存和網絡檔案系統協定引起的延遲,
* 此類執行個體提供的視圖可能與其他并發運作的程式所看到的視圖一緻,也可能不一緻。
* 不管這些程式是用什麼語言編寫的,也不管它們是在同一台機器上運作還是在其他機器上運作,這都是正确的。
* 任何此類不一緻的确切性質都是系統依賴性的,是以未指定。
*
* <p> 檔案通道是通過調用這個類定義的一個open方法來建立的。
* 還可以通過調用該對象的getChannel方法從現有的FileInputStream、
* FileOutputStream或RandomAccessFile對象擷取檔案通道,該方法傳回連接配接到同一基礎檔案的檔案通道。
* 如果檔案通道是從現有的流或随機通路檔案獲得的,那麼檔案通道的狀态與getChannel方法傳回通道的對象的狀态密切相關。
* 改變通道的位置,無論是顯式的還是讀寫位元組的,都會改變原始對象的檔案位置,反之亦然。
* 通過檔案通道更改檔案的長度将更改通過原始對象看到的長度,反之亦然。
* 通過寫入位元組來更改檔案的内容将更改原始對象看到的内容,反之亦然。
*
* <a name="open-mode"></a> <p>
* 在不同的時候,這個類指定需要一個“為讀取打開”、“為寫入打開”或“為讀寫打開”的執行個體。
* 通過java.io.FileInputStream的getChannel方法獲得的通道,可以進行讀取。
* 通過java.io.FileOutputStream的getChannel方法獲得的信道,可以進行寫入。
* 最後,通過java.io.RandomAccessFile的getChannel方法獲得的通道,
* 如果執行個體建立模式為“r”,可以進行讀取,
* 如果執行個體建立模式為“rw”,可以進行讀取和寫入,。
*
* <a name="append-mode"></a><p> 為寫入而打開的檔案通道可能處于追加模式,
* 例如,如果它是從通過調用FileOutputStream(file,boolean)構造函數并為第二個參數傳遞true建立的FileOutputStream中獲得的。
* 在這種模式下,每次相對寫操作的調用首先将位置推進到檔案的末尾,然後寫入所請求的資料。
* 位置的提升和資料的寫入是否在單個原子操作中完成是系統依賴的,是以未指定。
*
* @see java.io.FileInputStream#getChannel()
* @see java.io.FileOutputStream#getChannel()
* @see java.io.RandomAccessFile#getChannel()
*
* @author Mark Reinhold
* @author Mike McCloskey
* @author JSR-51 Expert Group
* @since 1.4
*/
public abstract class FileChannel
extends AbstractInterruptibleChannel
implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel

構造函數,字段NO_ATTRIBUTES,方法2個open,3個read,3個write
/**
* Initializes a new instance of this class.
*/
protected FileChannel() { }
/**
* 打開或建立一個檔案,傳回通路該檔案的檔案通道。
*
* <p> options參數決定如何打開檔案。
* StandardOpenOption.READ和WRITE選項決定是否應該打開檔案進行讀寫。
* 如果數組中不包含任何選項(或APPEND選項),則打開檔案進行讀取。
* 預設情況下,讀取或寫入從檔案的開頭開始。
*
* <p> 除了讀和寫之外,可能還會出現以下選項:
*
* <table ">
* <tr> <th>Option</th> <th>Description</th> </tr>
* <tr>
* <td> {@link StandardOpenOption#APPEND APPEND} </td>
* <td> 如果存在此選項,則打開檔案進行寫操作,每次調用通道的write方法都會先将該位置移到檔案的末尾,然後寫入需要的資料。
* 位置的提升和資料的寫入是否在單個原子操作中完成是系統相關的,是以未指定。
* 此選項不能與READ或TRUNCATE_EXISTING選項聯合使用。</td>
* </tr>
* <tr>
* <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
* <td> 如果存在此選項,則現有檔案将被截斷為0位元組的大小。
* 當隻打開檔案供閱讀時,此選項将被忽略。</td>
* </tr>
* <tr>
* <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
* <td> 如果存在此選項,則建立一個新檔案,如果檔案已經存在則失敗。
* 當建立一個檔案時,檢查該檔案是否存在,如果該檔案不存在,則建立該檔案,
* 檔案是否存在的檢查和檔案不存在時的建立相對于其他檔案系統操作來說是原子的。
* 當隻打開檔案供閱讀時,此選項将被忽略。</td>
* </tr>
* <tr>
* <td > {@link StandardOpenOption#CREATE CREATE} </td>
* <td> 如果存在此選項,則打開現有檔案(如果存在),否則建立一個新檔案。
* 當建立一個檔案時,檔案是否存在的檢查和檔案不存在時的建立相對于其他檔案系統操作來說是原子的。
* 如果還存在CREATE_NEW選項,或者檔案隻打開用于讀取,則忽略該選項。</td>
* </tr>
* <tr>
* <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
* <td> 當此選項存在時,實作将盡最大努力,在close方法關閉時,删除檔案。
* 如果close方法沒有被調用,那麼當Java虛拟機終止時,将盡力删除檔案。</td>
* </tr>
* <tr>
* <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
* <td> 當建立一個新檔案時,此選項是一個提示,新檔案将是稀少的。
* 當不建立新檔案時将忽略此選項。</td>
* </tr>
* <tr>
* <td> {@link StandardOpenOption#SYNC SYNC} </td>
* <td> 要求對檔案内容或中繼資料的每次更新都同步地寫入底層儲存設備。
* (請參閱同步I/O檔案完整性)。</td>
* </tr>
* <tr>
* <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
* <td> 要求對檔案内容的每次更新都同步地寫入底層儲存設備。
* (請參閱同步I/O檔案完整性)。</td>
* </tr>
* </table>
*
* <p> 實作還可能支援其他選項。
*
* <p> attrs參數是一個可選的FileAttribute數組,FileAttribute是在建立檔案時自動設定的。
*
* <p> 通過調用建立Path的提供程式FileSystemProvider的newFileChannel方法來建立新通道。
*
* @param path
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
* @param attrs
* An optional list of file attributes to set atomically when
* creating the file
*
* @return A new file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
* If the {@code path} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified, or the array contains an attribute that cannot be set
* atomically when creating the file
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an
* unspecified permission required by the implementation.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String)} method is invoked to check
* read access if the file is opened for reading. The {@link
* SecurityManager#checkWrite(String)} method is invoked to check
* write access if the file is opened for writing
*
* @since 1.7
*/
public static FileChannel open(Path path,
Set<? extends OpenOption> options,
FileAttribute<?>... attrs)
throws IOException
{
FileSystemProvider provider = path.getFileSystem().provider();
return provider.newFileChannel(path, options, attrs);
}
@SuppressWarnings({"unchecked", "rawtypes"}) // generic array construction
private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
/**
* 打開或建立一個檔案,傳回通路該檔案的檔案通道。
*
* <p> 此方法的調用行為與調用的方式完全相同
* <pre>
* fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute<?>[0]);
* </pre>
* 其中opts是選項數組中指定的一組選項。
*
* @param path
* The path of the file to open or create
* @param options
* Options specifying how the file is opened
*
* @return A new file channel
*
* @throws IllegalArgumentException
* If the set contains an invalid combination of options
* @throws UnsupportedOperationException
* If the {@code path} is associated with a provider that does not
* support creating file channels, or an unsupported open option is
* specified
* @throws IOException
* If an I/O error occurs
* @throws SecurityException
* If a security manager is installed and it denies an
* unspecified permission required by the implementation.
* In the case of the default provider, the {@link
* SecurityManager#checkRead(String)} method is invoked to check
* read access if the file is opened for reading. The {@link
* SecurityManager#checkWrite(String)} method is invoked to check
* write access if the file is opened for writing
*
* @since 1.7
*/
public static FileChannel open(Path path, OpenOption... options)
throws IOException
{
Set<OpenOption> set = new HashSet<OpenOption>(options.length);
Collections.addAll(set, options);
return open(path, set, NO_ATTRIBUTES);
}
// -- Channel operations --
/**
* 從這個通道讀取位元組序列到給定的緩沖區。
*
* <p> 位元組從該通道的目前檔案位置開始讀取,然後檔案位置根據實際讀取的位元組數更新。
* 否則,此方法的行為與ReadableByteChannel接口中指定的完全一樣。</p>
*/
public abstract int read(ByteBuffer dst) throws IOException;
/**
* 從這個通道讀取位元組序列到給定緩沖區的子序列。
*
* <p> 位元組從該通道的目前檔案位置開始讀取,然後檔案位置根據實際讀取的位元組數更新。
* 否則,此方法的行為與ScatteringByteChannel接口中指定的完全一樣。</p>
*/
public abstract long read(ByteBuffer[] dsts, int offset, int length)
throws IOException;
/**
* 從這個通道讀取位元組序列到給定的緩沖區。
*
* <p> 位元組從該通道的目前檔案位置開始讀取,然後檔案位置根據實際讀取的位元組數更新。
* 否則,此方法的行為與ScatteringByteChannel接口中指定的完全一樣。</p>
*/
public final long read(ByteBuffer[] dsts) throws IOException {
return read(dsts, 0, dsts.length);
}
/**
* 将一個位元組序列從給定的緩沖區寫入此通道。
*
* <p> 位元組從通道的目前檔案位置開始寫入,除非通道處于追加模式,在這種情況下,位置首先被推進到檔案的末尾。
* 如果有必要,檔案會增長以容納寫入的位元組,然後根據實際寫入的位元組數更新檔案位置。
* 否則,這個方法的行為與WritableByteChannel接口指定的完全一樣。</p>
*/
public abstract int write(ByteBuffer src) throws IOException;
/**
* 從給定緩沖區的子序列向該通道寫入位元組序列。
*
* <p> 位元組從通道的目前檔案位置開始寫入,除非通道處于追加模式,在這種情況下,位置首先被推進到檔案的末尾。
* 如果有必要,檔案會增長以容納寫入的位元組,然後根據實際寫入的位元組數更新檔案位置。
* 否則,該方法的行為與在GatheringByteChannelinterface中指定的完全一樣。</p>
*/
public abstract long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
/**
* 從給定緩沖區向該通道寫入位元組序列。
*
* <p> 位元組從通道的目前檔案位置開始寫入,除非通道處于追加模式,在這種情況下,位置首先被推進到檔案的末尾。
* 如果有必要,檔案會增長以容納寫入的位元組,然後根據實際寫入的位元組數更新檔案位置。
* 否則,該方法的行為與在GatheringByteChannelinterface中指定的完全一樣。</p>
*/
public final long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
方法2個position,size,truncate,force,transferTo,transferFrom,read,write
// -- Other operations --
/**
* 傳回通道的檔案位置
*
* @return This channel's file position,
* a non-negative integer counting the number of bytes
* from the beginning of the file to the current position
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract long position() throws IOException;
/**
* 設定該通道的檔案位置。
*
* <p> 将位置設定為大于檔案目前大小的值是合法的,但不會改變檔案的大小。
* 稍後嘗試在這個位置,讀取位元組将立即傳回檔案結束訓示。
* 以後在這種位置寫入位元組的嘗試将導緻檔案增長以容納新位元組;
* 前一個檔案結束位元組和新寫入位元組之間的任何位元組的值都是未指定的。</p>
*
* @param newPosition
* The new position, a non-negative integer counting
* the number of bytes from the beginning of the file
*
* @return This file channel
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IllegalArgumentException
* If the new position is negative
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract FileChannel position(long newPosition) throws IOException;
/**
* 傳回這個通道的檔案的目前大小
*
* @return The current size of this channel's file,
* measured in bytes
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract long size() throws IOException;
/**
* 将此通道的檔案截斷為給定的大小。
*
* <p> 如果給定的大小小于檔案的目前大小,那麼檔案将被截斷,丢棄檔案新結束以外的任何位元組。
* 如果給定的大小大于或等于檔案的目前大小,則檔案不會被修改。
* 在任何一種情況下,如果該通道的檔案位置大于給定的大小,那麼它就被設定為該大小。
* </p>
*
* @param size
* The new size, a non-negative byte count
*
* @return This file channel
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IllegalArgumentException
* If the new size is negative
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract FileChannel truncate(long size) throws IOException;
/**
* 強制将此通道檔案的任何更新寫入包含它的儲存設備。
*
* <p> 如果此通道的檔案駐留在本地儲存設備上,那麼當此方法傳回時,
* 可以保證建立了此通道以來的檔案,或者自上次調用此方法以來,對檔案所做的所有更改都已寫入該裝置。
* 這對于確定在系統崩潰時不丢失關鍵資訊非常有用。
*
* <p> 如果檔案不在本地裝置上,則不做這樣的保證。
*
* <p> metaData參數可用于限制此方法需要執行的I/O操作的數量。
* 為該參數傳遞false表示隻有對檔案内容的更新才需要寫入存儲器;
* 傳遞true表示對檔案内容和中繼資料的更新都必須寫入,這通常需要至少一次I/O操作。
* 這個參數是否真的有影響取決于底層作業系統,是以未指定。
*
* <p> 調用此方法可能導緻I/O操作發生,即使通道僅為讀取而打開。
* 例如,一些作業系統維護最後通路時間作為檔案中繼資料的一部分,并且每當讀取檔案時這段時間都會更新。
* 是否真的這樣做是系統依賴的,是以是未指定的。
*
* <p> 此方法隻能保證強制通過該類中定義的方法對該通道的檔案進行更改。
* 它可能強制也可能不強制,通過修改,通過調用map方法獲得的MappedByteBuffer的内容,而進行的更改。
* 調用映射位元組緩沖區的force方法将強制寫入對緩沖區内容所做的更改。</p>
*
* @param metaData
* If <tt>true</tt> then this method is required to force changes
* to both the file's content and metadata to be written to
* storage; otherwise, it need only force content changes to be
* written
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract void force(boolean metaData) throws IOException;
/**
* 從這個通道的檔案傳輸位元組到給定的可寫位元組通道。
*
* <p> 嘗試從該通道檔案中的給定位置開始讀取最多count位元組,并将它們寫入目标通道。
* 調用此方法可以或不可以傳遞所有請求的位元組;它是否這樣做取決于性質和狀态的管道。
* 如果此通道的檔案從給定位置開始包含的位元組數少于count位元組,或者如果目标通道是非阻塞的,
* 并且它的輸出緩沖區中空閑的位元組數少于count位元組,則傳輸的位元組數少于請求的位元組數。
*
* <p> 此方法不修改該通道的位置。如果給定的位置大于檔案的目前大小,則不傳輸位元組。
* 如果目标通道有一個位置,那麼從這個位置開始寫入位元組,然後這個位置增加寫入的位元組數。
*
* <p> 這種方法可能比簡單的循環(從這個通道讀取并寫入目标通道)高效得多。
* 許多作業系統可以直接将位元組從檔案系統緩存傳輸到目标通道,而不需要實際複制它們。</p>
*
* @param position
* The position within the file at which the transfer is to begin;
* must be non-negative
*
* @param count
* The maximum number of bytes to be transferred; must be
* non-negative
*
* @param target
* The target channel
*
* @return The number of bytes, possibly zero,
* that were actually transferred
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*
* @throws NonReadableChannelException
* If this channel was not opened for reading
*
* @throws NonWritableChannelException
* If the target channel was not opened for writing
*
* @throws ClosedChannelException
* If either this channel or the target channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes either channel
* while the transfer is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread while the
* transfer is in progress, thereby closing both channels and
* setting the current thread's interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract long transferTo(long position, long count,
WritableByteChannel target)
throws IOException;
/**
* 将位元組從給定的可讀通道傳輸到此通道的檔案中。
*
* <p> 嘗試從源通道讀取位元組數,并從給定位置開始将它們寫入該通道的檔案。
* 調用此方法可以或不可以傳輸所有請求的位元組;
* 它是否會這樣做,取決于管道的性質和狀态。
* 如果源通道剩餘的位元組數小于count,或者源通道是非阻塞的,
* 并且在它的輸入緩沖區中立即可用的位元組數小于count,那麼将被傳輸的位元組數小于請求的位元組數。
*
* <p> 此方法不修改該通道的位置。
* 如果給定的位置大于檔案的目前大小,則不傳輸位元組。
* 如果源通道有一個位置,那麼位元組将從這個位置開始讀取,然後這個位置将增加讀取的位元組數。
*
* <p> 這種方法可能比從源通道讀取并寫入該通道的簡單循環更有效。
* 許多作業系統可以直接将位元組從源通道傳輸到檔案系統緩存中,而不需要實際複制它們。</p>
*
* @param src
* The source channel
*
* @param position
* The position within the file at which the transfer is to begin;
* must be non-negative
*
* @param count
* The maximum number of bytes to be transferred; must be
* non-negative
*
* @return The number of bytes, possibly zero,
* that were actually transferred
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*
* @throws NonReadableChannelException
* If the source channel was not opened for reading
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If either this channel or the source channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes either channel
* while the transfer is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread while the
* transfer is in progress, thereby closing both channels and
* setting the current thread's interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract long transferFrom(ReadableByteChannel src,
long position, long count)
throws IOException;
/**
* 從給定的檔案位置開始,從這個通道讀取位元組序列到給定的緩沖區。
*
* <p> 這個方法的工作方式與read(ByteBuffer)方法相同,不同的是位元組是從給定的檔案位置而不是通道的目前位置開始讀取的。
* 這個方法不改變這個通道的位置。如果給定的位置大于檔案的目前大小,則不讀取位元組。</p>
*
* @param dst
* The buffer into which bytes are to be transferred
*
* @param position
* The file position at which the transfer is to begin;
* must be non-negative
*
* @return The number of bytes read, possibly zero, or <tt>-1</tt> if the
* given position is greater than or equal to the file's current
* size
*
* @throws IllegalArgumentException
* If the position is negative
*
* @throws NonReadableChannelException
* If this channel was not opened for reading
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the read operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the read operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract int read(ByteBuffer dst, long position) throws IOException;
/**
* 從給定的檔案位置開始,從給定的緩沖區向此通道寫入位元組序列。
*
* <p> 這個方法的工作方式與write(ByteBuffer)方法相同,
* 不同的是位元組是從給定的檔案位置而不是通道的目前位置開始寫入的。
* 此方法不修改該通道的位置。
* 如果給定的位置大于檔案的目前大小,那麼檔案将被擴充以容納新的位元組;
* 前一個檔案結束位元組和新寫入位元組之間的任何位元組的值都是未指定的。 </p>
*
* @param src
* The buffer from which bytes are to be transferred
*
* @param position
* The file position at which the transfer is to begin;
* must be non-negative
*
* @return The number of bytes written, possibly zero
*
* @throws IllegalArgumentException
* If the position is negative
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel
* while the write operation is in progress
*
* @throws ClosedByInterruptException
* If another thread interrupts the current thread
* while the write operation is in progress, thereby
* closing the channel and setting the current thread's
* interrupt status
*
* @throws IOException
* If some other I/O error occurs
*/
public abstract int write(ByteBuffer src, long position) throws IOException;
内部類MapMode
// -- Memory-mapped buffers --
/**
* 用于檔案映射模式的類型安全枚舉。
*
* @since 1.4
*
* @see java.nio.channels.FileChannel#map
*/
public static class MapMode {
/**
* 隻讀映射的模式。
*/
public static final MapMode READ_ONLY
= new MapMode("READ_ONLY");
/**
* 讀/寫映射的模式。
*/
public static final MapMode READ_WRITE
= new MapMode("READ_WRITE");
/**
* 私有(寫時複制)映射的模式。
*/
public static final MapMode PRIVATE
= new MapMode("PRIVATE");
private final String name;
private MapMode(String name) {
this.name = name;
}
/**
* 傳回描述此檔案映射模式的字元串。
*
* @return A descriptive string
*/
public String toString() {
return name;
}
}
方法map,2個lock,2個tryLock
/**
* 将此通道檔案的一個區域直接映射到記憶體中。
*
* <p> 檔案的一個區域可以在以下三種模式中被映射到記憶體:
* </p>
*
* <ul>
*
* <li><p>隻讀:任何修改緩存的嘗試都會導緻java.nio.ReadOnlyBufferException被抛出。</p></li>
*
* <li><p> 讀/寫:對結果緩沖區所做的更改将最終傳播到檔案中;它們可能被其他映射了相同檔案的程式通路,
* 也可能不被通路。</p></li>
*
* <li><p> Private:對結果緩沖區所做的更改将不會傳播到該檔案,其他程式不可見這些改變;
* 相反,它們将導緻建立緩沖區中修改過的部分的私有複制。</p></li>
*
* </ul>
*
* <p> 對于隻讀映射,此通道必須已打開以供讀取;
* 對于讀/寫或私有映射,此通道必須同時為讀和寫打開。
*
* <p> 這個方法傳回的MappedByteBuffer将有一個0的位置和size的限制和容量;
* 它的标記将是未定義的。
* 緩沖區及其所代表的映射将保持有效,直到緩沖區本身被垃圾收集為止。
*
* <p> 映射一旦建立,就不依賴于用于建立它的檔案通道。
* 特别是,關閉通道對映射的有效性沒有影響。
*
* <p> 記憶體映射檔案的許多細節本質上依賴于底層作業系統,是以未指定。
* 當請求的區域不完全包含在此通道的檔案中時,此方法的行為是未指定的。
* 這個程式或另一個程式對基礎檔案的内容或大小所做的更改是否傳播到緩沖區是未指定的。
* 将對緩沖區的更改傳播到檔案的速率未指定。
*
* <p> 對于大多數作業系統來說,将檔案映射到記憶體要比通過通常的讀寫方法讀寫幾十千位元組的資料要昂貴得多。
* 從性能的角度來看,通常隻值得将相對較大的檔案映射到記憶體中。</p>
*
* @param mode
* One of the constants {@link MapMode#READ_ONLY READ_ONLY}, {@link
* MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE
* PRIVATE} defined in the {@link MapMode} class, according to
* whether the file is to be mapped read-only, read/write, or
* privately (copy-on-write), respectively
*
* @param position
* The position within the file at which the mapped region
* is to start; must be non-negative
*
* @param size
* The size of the region to be mapped; must be non-negative and
* no greater than {@link java.lang.Integer#MAX_VALUE}
*
* @return The mapped byte buffer
*
* @throws NonReadableChannelException
* If the <tt>mode</tt> is {@link MapMode#READ_ONLY READ_ONLY} but
* this channel was not opened for reading
*
* @throws NonWritableChannelException
* If the <tt>mode</tt> is {@link MapMode#READ_WRITE READ_WRITE} or
* {@link MapMode#PRIVATE PRIVATE} but this channel was not opened
* for both reading and writing
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*
* @throws IOException
* If some other I/O error occurs
*
* @see java.nio.channels.FileChannel.MapMode
* @see java.nio.MappedByteBuffer
*/
public abstract MappedByteBuffer map(MapMode mode,
long position, long size)
throws IOException;
// -- Locks --
/**
* 擷取此通道檔案的給定區域上的鎖。
*
* <p> 此方法的調用将阻塞,直到區域可以被鎖定、此通道被關閉或調用線程被中斷(以先發生的為準)。
*
* <p> 如果在調用此方法期間,另一個線程關閉此通道,則将抛出AsynchronousCloseException。
*
* <p> 如果調用線程在等待擷取鎖的過程中被中斷,那麼它的中斷狀态将被設定,并抛出FileLockInterruptionException。
* 如果調用者的中斷狀态設定在這個方法被調用時,那麼這個異常将立即被抛出;線程的中斷狀态不會被改變。
*
* <p> 由position和size參數指定的區域不需要包含在實際的底層檔案中,甚至不需要重疊。
* 鎖定區域的大小固定;
* 如果一個被鎖定的區域最初包含檔案的結尾,并且檔案超出了該區域,那麼該檔案的新部分将不會被鎖覆寫。
* 如果預期一個檔案的大小會增長,并且需要對整個檔案加鎖,那麼應該鎖定一個從0開始,且不小于預期檔案最大大小的區域。
* 零參數lock()方法隻是鎖定一個長度為Long.MAX_VALUE的區域。
*
* <p> 一些作業系統不支援共享鎖,在這種情況下,對共享鎖的請求會自動轉換為對獨占鎖的請求。
* 新獲得的鎖是共享的還是獨占的,可以通過調用結果鎖對象的isShared方法來測試。
*
* <p> 檔案鎖代表整個Java虛拟機。
* 它們不适用于控制同一虛拟機中的多個線程對檔案的通路。</p>
*
* @param position
* The position at which the locked region is to start; must be
* non-negative
*
* @param size
* The size of the locked region; must be non-negative, and the sum
* <tt>position</tt> + <tt>size</tt> must be non-negative
*
* @param shared
* <tt>true</tt> to request a shared lock, in which case this
* channel must be open for reading (and possibly writing);
* <tt>false</tt> to request an exclusive lock, in which case this
* channel must be open for writing (and possibly reading)
*
* @return A lock object representing the newly-acquired lock
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel while the invoking
* thread is blocked in this method
*
* @throws FileLockInterruptionException
* If the invoking thread is interrupted while blocked in this
* method
*
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or if another thread is already
* blocked in this method and is attempting to lock an overlapping
* region
*
* @throws NonReadableChannelException
* If <tt>shared</tt> is <tt>true</tt> this channel was not
* opened for reading
*
* @throws NonWritableChannelException
* If <tt>shared</tt> is <tt>false</tt> but this channel was not
* opened for writing
*
* @throws IOException
* If some other I/O error occurs
*
* @see #lock()
* @see #tryLock()
* @see #tryLock(long,long,boolean)
*/
public abstract FileLock lock(long position, long size, boolean shared)
throws IOException;
/**
* 擷取此通道檔案的排他鎖。
*
* <p> 以fc.lock()形式調用這個方法的行為與調用的方式完全相同
*
* <pre>
* fc.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false) </pre>
*
* @return A lock object representing the newly-acquired lock
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws AsynchronousCloseException
* If another thread closes this channel while the invoking
* thread is blocked in this method
*
* @throws FileLockInterruptionException
* If the invoking thread is interrupted while blocked in this
* method
*
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or if another thread is already
* blocked in this method and is attempting to lock an overlapping
* region of the same file
*
* @throws NonWritableChannelException
* If this channel was not opened for writing
*
* @throws IOException
* If some other I/O error occurs
*
* @see #lock(long,long,boolean)
* @see #tryLock()
* @see #tryLock(long,long,boolean)
*/
public final FileLock lock() throws IOException {
return lock(0L, Long.MAX_VALUE, false);
}
/**
* 試圖擷取此通道檔案的給定區域上的鎖。
*
* <p> 這個方法不會阻塞。調用總是立即傳回,要麼獲得了請求區域上的鎖,要麼失敗了。
* 如果它因為另一個程式持有重疊的鎖而無法擷取鎖,那麼它将傳回null。
* 如果它因為任何其他原因而無法獲得鎖,則抛出一個适當的異常。
*
* <p> 由position和size參數指定的區域不需要包含在實際的底層檔案中,甚至不需要重疊。
* 鎖定區域的大小固定;如果一個被鎖定的區域最初包含檔案的結尾,并且檔案超出了該區域,那麼該檔案的新部分将不會被鎖覆寫。
* 如果預期一個檔案的大小會增長,并且需要對整個檔案加鎖,那麼應該鎖定一個從0開始,且不小于預期檔案最大大小的區域。
* 零參數tryLock()方法隻是鎖定一個長度為Long.MAX_VALUE的區域。
*
* <p> 一些作業系統不支援共享鎖,在這種情況下,對共享鎖的請求會自動轉換為對獨占鎖的請求。
* 新獲得的鎖是共享的還是獨占的,可以通過調用結果鎖對象的isShared方法來測試。
*
* <p> 檔案鎖代表整個Java虛拟機。
* 它們不适用于控制同一虛拟機中的多個線程對檔案的通路。</p>
*
* @param position
* The position at which the locked region is to start; must be
* non-negative
*
* @param size
* The size of the locked region; must be non-negative, and the sum
* <tt>position</tt> + <tt>size</tt> must be non-negative
*
* @param shared
* <tt>true</tt> to request a shared lock,
* <tt>false</tt> to request an exclusive lock
*
* @return A lock object representing the newly-acquired lock,
* or <tt>null</tt> if the lock could not be acquired
* because another program holds an overlapping lock
*
* @throws IllegalArgumentException
* If the preconditions on the parameters do not hold
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or if another thread is already
* blocked in this method and is attempting to lock an overlapping
* region of the same file
*
* @throws IOException
* If some other I/O error occurs
*
* @see #lock()
* @see #lock(long,long,boolean)
* @see #tryLock()
*/
public abstract FileLock tryLock(long position, long size, boolean shared)
throws IOException;
/**
* 試圖擷取此通道檔案的獨占鎖。
*
* <p> 調用fc.tryLock()形式的這個方法的行為與調用的方式完全相同
*
* <pre>
* fc.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
*
* @return A lock object representing the newly-acquired lock,
* or <tt>null</tt> if the lock could not be acquired
* because another program holds an overlapping lock
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws OverlappingFileLockException
* If a lock that overlaps the requested region is already held by
* this Java virtual machine, or if another thread is already
* blocked in this method and is attempting to lock an overlapping
* region
*
* @throws IOException
* If some other I/O error occurs
*
* @see #lock()
* @see #lock(long,long,boolean)
* @see #tryLock(long,long,boolean)
*/
public final FileLock tryLock() throws IOException {
return tryLock(0L, Long.MAX_VALUE, false);
}