NIO--Channel
類結(jié)構(gòu)圖
接口
Channel
public interface Channel extends Closeable {public boolean isOpen();public void close() throws IOException;}InterruptibleChannel
標(biāo)記接口,表示支持中斷
AsynchronousChannel
標(biāo)記接口,表示支持異步。
public interface AsynchronousChannel extends Channel {@Overridevoid close() throws IOException; }NetworkChannel
具有網(wǎng)絡(luò)功能。
public interface NetworkChannel extends Channel {NetworkChannel bind(SocketAddress local) throws IOException;SocketAddress getLocalAddress() throws IOException;<T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException;<T> T getOption(SocketOption<T> name) throws IOException;Set<SocketOption<?>> supportedOptions(); }MulticastChannel
具有多播功能
public interface MulticastChannel extends NetworkChannel {@Override void close() throws IOException;MembershipKey join(InetAddress group, NetworkInterface interf) throws IOException;MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source) throws IOException; }ReadableByteChannel
增加了read(...)方法。
public interface ReadableByteChannel extends Channel {public int read(ByteBuffer dst) throws IOException;}ScatteringByteChannel
支持從多個(gè)ByteBuffer中read數(shù)據(jù)。
public interface ScatteringByteChannel extends ReadableByteChannel {public long read(ByteBuffer[] dsts, int offset, int length) throws IOException;public long read(ByteBuffer[] dsts) throws IOException; }WritableByteChannel
增加了write(...)方法。
public interface WritableByteChannel extends Channel {public int write(ByteBuffer src) throws IOException; }GatheringByteChannel
支持把數(shù)據(jù)write到多個(gè)ByteBuffer中。
public interface GatheringByteChannelextends WritableByteChannel {public long write(ByteBuffer[] srcs, int offset, int length) throws IOException;public long write(ByteBuffer[] srcs) throws IOException;}ByteChannel
標(biāo)記接口,表示具有read,write功能。
public interface ByteChannel extends ReadableByteChannel, WritableByteChannel {}SeekableByteChannel
具有定位方法。
public interface SeekableByteChannel extends ByteChannel {@Overrideint read(ByteBuffer dst) throws IOException;@Overrideint write(ByteBuffer src) throws IOException;//**********定位方法**********long position() throws IOException;SeekableByteChannel position(long newPosition) throws IOException;long size() throws IOException;SeekableByteChannel truncate(long size) throws IOException; }實(shí)現(xiàn)類
I/O可以分為廣義的兩大類別:File I/O和StreamI/O。那么相應(yīng)地通道也有兩種類型,它們是文件(file)通道和套接字(socket)通道。套接字(socket)通道又分為:SocketChannel、ServerSocketChannel和DatagramChannel。
FileChannel
文件通道總是阻塞式的,因此不能被置于非阻塞模式。
FileChannel對(duì)象不能直接創(chuàng)建。一個(gè)FileChannel實(shí)例只能通過(guò)在一個(gè)打開(kāi)的file對(duì)象(RandomAccessFile、FileInputStream或FileOutputStream)上調(diào)用getChannel()方法獲取。調(diào)用getChannel( )方法會(huì)返回一個(gè)連接到相同文件的FileChannel對(duì)象且該FileChannel對(duì)象具有與file對(duì)象相同的訪問(wèn)權(quán)。
FileChannel對(duì)象是線程安全(thread-safe)的。多個(gè)進(jìn)程可以在同一個(gè)實(shí)例上并發(fā)調(diào)用方法而不會(huì)引起任何問(wèn)題,不過(guò)并非所有的操作都是多線程的(multithreaded)。影響通道位置或者影響文件大小的操作都是單線程的(single-threaded)。如果有一個(gè)線程已經(jīng)在執(zhí)行會(huì)影響通道位置或文件大小的操作,那么其他嘗試進(jìn)行此類操作之一的線程必須等待。并發(fā)行為也會(huì)受到底層的操作系統(tǒng)或文件系統(tǒng)影響。
文件訪問(wèn)
position值決定文件中哪一處的數(shù)據(jù)接下來(lái)將被讀或者寫(xiě)。
將通道position設(shè)置為一個(gè)負(fù)值會(huì)導(dǎo)致java.lang.IllegalArgumentException異常
把position設(shè)置到超出文件尾,這樣做會(huì)把position設(shè)置為指定值而不改變文件大小。假如在將position設(shè)置為超出當(dāng)前文件大小時(shí)實(shí)現(xiàn)了一個(gè)read()方法,那么會(huì)返回一個(gè)文件尾(end-of-file)條件;倘若此時(shí)實(shí)現(xiàn)的是一個(gè)write( )方法則會(huì)引起文件增長(zhǎng)以容納寫(xiě)入的字節(jié),具體行為類似于實(shí)現(xiàn)一個(gè)絕對(duì)write( )并可能導(dǎo)致出現(xiàn)一個(gè)文件空洞(filehole)。
FileChannel位置(position)是從底層的文件描述符獲得的,該position同時(shí)被作為通道引用獲取來(lái)源的文件對(duì)象共享。這也就意味著一個(gè)對(duì)象對(duì)該position的更新可以被另一個(gè)對(duì)象看到。
帶position參數(shù)的絕對(duì)形式的read( )和write( )方法在返回值時(shí)不會(huì)改變當(dāng)前的文件position。
truncate( )方法會(huì)砍掉您所指定的新size值之外的所有數(shù)據(jù)。文件的position會(huì)被設(shè)置為所提供的新size值。
force( )方法要求文件的所有待定修改立即同步到磁盤。
文件鎖定
鎖的對(duì)象是文件而不是通道或線程,這意味著文件鎖不適用于判優(yōu)同一臺(tái)Java虛擬機(jī)上的多個(gè)線程發(fā)起的訪問(wèn)。
如果一個(gè)線程在某個(gè)文件上獲得了一個(gè)獨(dú)占鎖,然后第二個(gè)線程利用一個(gè)單獨(dú)打開(kāi)的通道來(lái)請(qǐng)求該文件的獨(dú)占鎖,那么第二個(gè)線程的請(qǐng)求會(huì)被批準(zhǔn)。但如果這兩個(gè)線程運(yùn)行在不同的Java虛擬機(jī)上,那么第二個(gè)線程會(huì)阻塞,因?yàn)殒i最終是由操作系統(tǒng)或文件系統(tǒng)來(lái)判優(yōu)的并且幾乎總是在進(jìn)程級(jí)而非線程級(jí)上判優(yōu)。鎖都是與一個(gè)文件關(guān)聯(lián)的,而不是與單個(gè)的文件句柄或通道關(guān)聯(lián)。
public abstract FileLock lock(long position, long size, boolean shared) throws IOException; public final FileLock lock() throws IOException {return lock(0L, Long.MAX_VALUE, false); } public abstract FileLock tryLock(long position, long size, boolean shared) throws IOException;public final FileLock tryLock() throws IOException {return tryLock(0L, Long.MAX_VALUE, false); }鎖是在文件內(nèi)部區(qū)域上獲得的。
要獲得一個(gè)共享鎖,必須先以只讀權(quán)限打開(kāi)文件,而請(qǐng)求獨(dú)占鎖時(shí)則需要寫(xiě)權(quán)限。
鎖定區(qū)域的范圍不一定要限制在文件的size值以內(nèi),鎖可以擴(kuò)展從而超出文件尾。因此,可以提前把待寫(xiě)入數(shù)據(jù)的區(qū)域鎖定,也可以鎖定一個(gè)不包含任何文件內(nèi)容的區(qū)域,比如文件最后一個(gè)字節(jié)以外的區(qū)域。如果之后文件增長(zhǎng)到達(dá)那塊區(qū)域,那么文件鎖就可以保護(hù)該區(qū)域的文件內(nèi)容了。相反地,如果鎖定了文件的某一塊區(qū)域,然后文件增長(zhǎng)超出了那塊區(qū)域,那么新增加的文件內(nèi)容將不會(huì)受到文件鎖的保護(hù)。
tryLock( )的方法是lock( )方法的非阻塞變體。和lock( )方法起相同的作用,不過(guò)如果請(qǐng)求的鎖不能立即獲取到則會(huì)返回一個(gè)null。
FileLock
FileLock類封裝一個(gè)鎖定的文件區(qū)域。FileLock對(duì)象由FileChannel創(chuàng)建并且總是關(guān)聯(lián)到那個(gè)特定的通道實(shí)例。
public abstract class FileLock {public final FileChannel channel( ); public final long position( ); public final long size( ) ;public final boolean isShared( ) ;public final boolean overlaps (long position, long size) ;public abstract boolean isValid( ); public abstract void release( ) throws IOException; }channel( )方法來(lái)查詢一個(gè)lock對(duì)象以判斷它是由哪個(gè)通道創(chuàng)建的
一個(gè)FileLock對(duì)象創(chuàng)建之后即有效,直到它的release()方法被調(diào)用或它所關(guān)聯(lián)的通道被關(guān)閉或Java虛擬機(jī)關(guān)閉時(shí)才會(huì)失效。我們可以通過(guò)調(diào)用isValid()布爾方法來(lái)測(cè)試一個(gè)鎖的有效性。一個(gè)鎖的有效性可能會(huì)隨著時(shí)間而改變,不過(guò)它的其他屬性——位置(position)、范圍大小(size)和獨(dú)占性(exclusivity)——在創(chuàng)建時(shí)即被確定,不會(huì)隨著時(shí)間而改變。
isShared()方法來(lái)測(cè)試一個(gè)鎖以判斷它是共享的還是獨(dú)占的。如果底層的操作系統(tǒng)或文件系統(tǒng)不支持共享鎖,那么該方法將總是返回false值。
overlaps( )方法來(lái)查詢一個(gè)FileLock對(duì)象是否與一個(gè)指定的文件區(qū)域重疊。這將使您可以迅速判斷您擁有的鎖是否與一個(gè)感興趣的區(qū)域(region of interest)有交叉
使用完一個(gè)鎖后而不釋放它的話,可能會(huì)導(dǎo)致沖突或者死鎖
內(nèi)存映射文件
public abstract MappedByteBuffer map(MapMode mode,long position, long size) throws IOException;map()的方法,該方法可以在一個(gè)打開(kāi)的文件和一個(gè)特殊類型的ByteBuffer之間建立一個(gè)虛擬內(nèi)存映射。它會(huì)創(chuàng)建一個(gè)由磁盤文件支持的虛擬內(nèi)存映射(virtual memory mapping)并在那塊虛擬內(nèi)存空間外部封裝一個(gè)MappedByteBuffer對(duì)象
MappedByteBuffer對(duì)象的行為在多數(shù)方面類似一個(gè)基于內(nèi)存的緩沖區(qū),只不過(guò)該對(duì)象的數(shù)據(jù)元素存儲(chǔ)在磁盤上的一個(gè)文件中。調(diào)用get()方法會(huì)從磁盤文件中獲取數(shù)據(jù),此數(shù)據(jù)反映該文件的當(dāng)前內(nèi)容。相似地,對(duì)映射的緩沖區(qū)實(shí)現(xiàn)一個(gè)put()會(huì)更新磁盤上的那個(gè)文件,并且您做的修改對(duì)于該文件的其他閱讀者也是可見(jiàn)的。
通過(guò)內(nèi)存映射機(jī)制來(lái)訪問(wèn)一個(gè)文件會(huì)比使用常規(guī)方法讀寫(xiě)高效得多,甚至比使用通道的效率都高。因?yàn)椴恍枰雒鞔_的系統(tǒng)調(diào)用,那會(huì)很消耗時(shí)間。更重要的是,操作系統(tǒng)的虛擬內(nèi)存可以自動(dòng)緩存內(nèi)存頁(yè)(memory page)。這些頁(yè)是用系統(tǒng)內(nèi)存來(lái)緩存的,所以不會(huì)消耗Java虛擬機(jī)內(nèi)存堆(memory heap)。
與文件鎖的范圍機(jī)制不一樣,映射文件的范圍不應(yīng)超過(guò)文件的實(shí)際大小。如果請(qǐng)求一個(gè)超出文件大小的映射,文件會(huì)被增大以匹配映射的大小。即使您請(qǐng)求的是一個(gè)只讀映射,map( )方法也會(huì)嘗試這樣做。
映射模式:
- READ_ONLY
- READ_WRITE
- PRIVATE:寫(xiě)時(shí)拷貝(copy-on-write)的映射
寫(xiě)時(shí)拷貝(copy-on-write)的映射。這意味著您通過(guò)put()方法所做的任何修改都會(huì)導(dǎo)致產(chǎn)生一個(gè)私有的數(shù)據(jù)拷貝并且該拷貝中的數(shù)據(jù)只有MappedByteBuffer實(shí)例可以看到。該過(guò)程不會(huì)對(duì)底層文件做任何修改,而且一旦緩沖區(qū)被施以垃圾收集動(dòng)作(garbagecollected),那些修改都會(huì)丟失。盡管寫(xiě)時(shí)拷貝的映射可以防止底層文件被修改,您也必須以read/write權(quán)限來(lái)打開(kāi)文件以建立MapMode.PRIVATE映射。只有這樣,返回的MappedByteBuffer對(duì)象才能允許使用put( )方法。
映射緩沖區(qū)沒(méi)有綁定到創(chuàng)建它們的通道上。關(guān)閉相關(guān)聯(lián)的FileChannel不會(huì)破壞映射,只有丟棄緩沖區(qū)對(duì)象本身才會(huì)破壞該映射。
Channel-to-Channel傳輸
由于經(jīng)常需要從一個(gè)位置將文件數(shù)據(jù)批量傳輸?shù)搅硪粋€(gè)位置,FileChannel類添加了一些優(yōu)化方法來(lái)提高該傳輸過(guò)程的效率:
public abstract long transferFrom(ReadableByteChannel src, long position, long count)throws IOException; public abstract long transferTo(long position, long count, WritableByteChannel target)throws IOException;transferTo( )和transferFrom( )方法允許將一個(gè)通道交叉連接到另一個(gè)通道,而不需要通過(guò)一個(gè)中間緩沖區(qū)來(lái)傳遞數(shù)據(jù)。只有FileChannel類有這兩個(gè)方法,因此channel-to-channel傳輸中通道之一必須是FileChannel。
直接的通道傳輸不會(huì)更新與某個(gè)FileChannel關(guān)聯(lián)的position值。請(qǐng)求的數(shù)據(jù)傳輸將從position參數(shù)指定的位置開(kāi)始,傳輸?shù)淖止?jié)數(shù)不超過(guò)count參數(shù)的值。實(shí)際傳輸?shù)淖止?jié)數(shù)會(huì)由方法返回,可能少于您請(qǐng)求的字節(jié)數(shù)。
示例:
private static void catFiles (WritableByteChannel target, String [] files) throws Exception
{
for (int i = 0; i < files.length; i++)
{
???? FileInputStream fis = new FileInputStream (files [i]);
???? FileChannel channel = fis.getChannel( );
???? channel.transferTo (0, channel.size( ), target);
???? channel.close( );
???? fis.close( );
}
}
Socket通道
socket通道類可以運(yùn)行非阻塞模式并且是可選擇的.
DatagramChannel和SocketChannel實(shí)現(xiàn)定義讀和寫(xiě)功能的接口而ServerSocketChannel不實(shí)現(xiàn)。ServerSocketChannel負(fù)責(zé)監(jiān)聽(tīng)傳入的連接和創(chuàng)建新的SocketChannel對(duì)象,它本身從不傳輸數(shù)據(jù)。
全部socket通道類(DatagramChannel、SocketChannel和ServerSocketChannel)在被實(shí)例化時(shí)都會(huì)創(chuàng)建一個(gè)對(duì)等socket對(duì)象。
非阻塞模式
Socket通道可以在非阻塞模式下運(yùn)行。傳統(tǒng)Java socket是阻塞的。要把一個(gè)socket通道置于非阻塞模式,我們要依靠所有socket通道類的公有超級(jí)類:SelectableChannel。
public abstract class SelectableChannel extends AbstractInterruptibleChannel implements Channel {......public abstract SelectableChannel configureBlocking(boolean block) throws IOException;public abstract boolean isBlocking();public abstract Object blockingLock();}configureBlocking()方法設(shè)置或重新設(shè)置一個(gè)通道的阻塞模式,參數(shù)值為true則設(shè)為阻塞模式,參數(shù)值為false值設(shè)為非阻塞模式。
isBlocking( )方法來(lái)判斷某個(gè)socket通道當(dāng)前處于哪種模式
SocketChannel sc = SocketChannel.open( );
sc.configureBlocking (false);
// nonblocking ...
if ( ! sc.isBlocking( ))
{ doSomething (cs); }
blockingLock()方法,防止socket通道的阻塞模式被更改。該方法會(huì)返回一個(gè)非透明的對(duì)象引用。返回的對(duì)象是通道實(shí)現(xiàn)修改阻塞模式時(shí)內(nèi)部使用的。只有擁有此對(duì)象的鎖的線程才能更改通道的阻塞模式(對(duì)象的鎖是用同步的Java密碼獲取的,它不同于lock( )方法)
Socket socket = null;
Object lockObj = serverChannel.blockingLock( );
// have a handle to the lock object, but haven't locked it yet
// may block here until lock is acquired
synchronize (lockObj) {
???????? // This thread now owns the lock; mode can't be changed
???????? boolean prevState = serverChannel.isBlocking( );
???????? serverChannel.configureBlocking (false);
??????? socket = serverChannel.accept( );
??????? serverChannel.configureBlocking (prevState);
?}
?// lock is now released, mode is allowed to change
?if (socket != null)
?{
?doSomethingWithTheSocket (socket);
?}
ServerSocketChannel
ServerSocketChannel是一個(gè)基于通道的socket監(jiān)聽(tīng)器。同我java.net.ServerSocket執(zhí)行相同的基本任務(wù),不過(guò)它增加了通道語(yǔ)義,因此能夠在非阻塞模式下運(yùn)行。
用靜態(tài)的open()工廠方法創(chuàng)建一個(gè)新的ServerSocketChannel對(duì)象,將會(huì)返回同一個(gè)未綁定的java.net.ServerSocket關(guān)聯(lián)的通道。該對(duì)等ServerSocket可以通過(guò)在返回的ServerSocketChannel上調(diào)用socket( )方法來(lái)獲取。
?ServerSocketChannel ssc = ServerSocketChannel.open( );
?ServerSocket serverSocket = ssc.socket( );
?serverSocket.bind (new InetSocketAddress (1234));
accept( )方法在阻塞模式下,總是阻塞并返回一個(gè)java.net.Socket對(duì)象,返回的對(duì)象能夠在非阻塞模式下運(yùn)行
如果以非阻塞模式被調(diào)用,當(dāng)沒(méi)有傳入連接在等待時(shí),ServerSocketChannel.accept( )會(huì)立即返回null
?ServerSocketChannel ssc = ServerSocketChannel.open( );
?ServerSocket serverSocket = ssc.socket( );
?serverSocket.bind (new InetSocketAddress (1234));
?
?ByteBuffer buffer = ByteBuffer.wrap (GREETING.getBytes( ));
?ServerSocketChannel ssc = ServerSocketChannel.open( );
?
?ssc.socket( ).bind (new InetSocketAddress (port));
//非阻塞模式
?ssc.configureBlocking (false);
?while (true)
?{
???? ...
???? SocketChannel sc = ssc.accept( );
???? if (sc == null) {
???? ...
???? } else {
???? ...
???? }
?}
SocketChannel
open( )方法可以創(chuàng)建一個(gè)新的SocketChannel對(duì)象,而在新創(chuàng)建的SocketChannel上調(diào)用socket( )方法能返回它對(duì)等的Socket對(duì)象;在該Socket上調(diào)用getChannel( )方法則能返回最初的那個(gè)SocketChannel。
新創(chuàng)建的SocketChannel雖已打開(kāi)卻是未連接的。可以通過(guò)在通道上直接調(diào)用connect( )方法或在通道關(guān)聯(lián)的Socket對(duì)象上調(diào)用connect( )來(lái)將該socket通道連接。isConnected( )方法來(lái)測(cè)試某個(gè)SocketChannel當(dāng)前是否已連接
調(diào)用finishConnect( )方法來(lái)完成連接過(guò)程,該方法任何時(shí)候都可以安全地進(jìn)行調(diào)用。假如在一個(gè)非阻塞模式的SocketChannel對(duì)象上調(diào)用finishConnect( )方法,將可能出現(xiàn)下列情形之一:
- ?connect( )方法尚未被調(diào)用。那么將產(chǎn)生NoConnectionPendingException異常。
- 連接建立過(guò)程正在進(jìn)行,尚未完成。那么什么都不會(huì)發(fā)生,finishConnect( )方法會(huì)立即返回false值。
- 在非阻塞模式下調(diào)用connect( )方法之后,SocketChannel又被切換回了阻塞模式。那么如果有必要的話,調(diào)用線程會(huì)阻塞直到連接建立完成,finishConnect( )方法接著就會(huì)返回true值。
- 在初次調(diào)用connect( )或最后一次調(diào)用finishConnect( )之后,連接建立過(guò)程已經(jīng)完成。那么SocketChannel對(duì)象的內(nèi)部狀態(tài)將被更新到已連接狀態(tài),finishConnect( )方法會(huì)返回true值,然后SocketChannel對(duì)象就可以被用來(lái)傳輸數(shù)據(jù)了。
- 連接已經(jīng)建立。那么什么都不會(huì)發(fā)生,finishConnect( )方法會(huì)返回true值。
Socket通道是線程安全的。并發(fā)訪問(wèn)時(shí)無(wú)需特別措施來(lái)保護(hù)發(fā)起訪問(wèn)的多個(gè)線程,不過(guò)任何時(shí)候都只有一個(gè)讀操作和一個(gè)寫(xiě)操作在進(jìn)行中。
connect( )和finishConnect( )方法是互相同步的,并且只要其中一個(gè)操作正在進(jìn)行,任何讀或?qū)懙姆椒ㄕ{(diào)用都會(huì)阻塞,即使是在非阻塞模式下
DatagramChannel
SocketChannel模擬連接導(dǎo)向的流協(xié)議(如TCP/IP),DatagramChannel則模擬包導(dǎo)向的無(wú)連接協(xié)議(如UDP/IP)
DatagramChannel對(duì)象既可以充當(dāng)服務(wù)器(監(jiān)聽(tīng)者)也可以充當(dāng)客戶端(發(fā)送者)
DatagramChannel是無(wú)連接的
管道
管道就是一個(gè)用來(lái)在兩個(gè)實(shí)體之間單向傳輸數(shù)據(jù)的導(dǎo)管
public abstract class Pipe {protected Pipe() { }public abstract SourceChannel source();public abstract SinkChannel sink();public static Pipe open() throws IOException {return SelectorProvider.provider().openPipe();} }Pipe類創(chuàng)建一對(duì)提供環(huán)回機(jī)制的Channel對(duì)象。這兩個(gè)通道的遠(yuǎn)端是連接起來(lái)的,以便任何寫(xiě)在SinkChannel對(duì)象上的數(shù)據(jù)都能出現(xiàn)在SourceChannel對(duì)象。唯一可保證的是寫(xiě)到SinkChannel中的字節(jié)都能按照同樣的順序在SourceChannel上重現(xiàn)。
Pipe pipe = Pipe.open( );
WritableByteChannel w = pipe.sink( );
ReadableByteChannel r = pipe.source( );
w.write (buffer);
.......
r.read (buffer);
通道工具類
java.nio.channels.Channels
| 方法 | 返回 | 描述 |
| newChannel (InputStream in) | ?ReadableByteChannel | 返回一個(gè)將從給定的輸入流讀取數(shù)據(jù)的通道。 |
| newChannel (OutputStream out)? | WritableByteChannel | 返回一個(gè)將向給定的輸出流寫(xiě)入數(shù)據(jù)的通道。 |
| newInputStream (ReadableByteChannel ch) | ?InputStream? | 返回一個(gè)將從給定的通道讀取字節(jié)的流。 |
| newOutputStream (WritableByteChannel ch) | ?OutputStream | 返回一個(gè)將向給定的通道寫(xiě)入字節(jié)的流。 |
| newReader (ReadableByteChannel ch, CharsetDecoder dec, int minBufferCap) | ?Reader? | 返回一個(gè)reader,它將從給定的通道讀取字節(jié)并依據(jù)提供的CharsetDecoder對(duì)讀取到的字節(jié)進(jìn)行解碼 |
| newReader(ReadableByteChannel ch, String csName) | ?Reader? | 返回一個(gè)reader,它將從給定的通道讀取字節(jié)并依據(jù)提供的字符集名稱將讀取到的字節(jié)解碼成字符。 |
| newWriter (WritableByteChannel ch, CharsetEncoder dec, int minBufferCap) | ?Writer | 返回一個(gè)writer,它將使用提供的CharsetEncoder對(duì)象對(duì)字符編碼并寫(xiě)到給定的通道中。 |
| newWriter (WritableByteChannel ch, String csName) | ?Writer? | 返回一個(gè)writer,它將依據(jù)提供的字符集名稱對(duì)字符編碼并寫(xiě)到給定的通道中。 |
?
總結(jié)
以上是生活随笔為你收集整理的NIO--Channel的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spring--IoC(2)
- 下一篇: NIO--Selector