作者:mobiledu2502889497 | 来源:互联网 | 2023-09-25 15:37
一 点睛通道用于数据的双向传输,即一个通道既可以用于读数据,又可以用于写数据。注意,这点不同于 I/O 中的 Stream,Stream 是单向的(只能是输入
一 点睛
通道用于数据的双向传输,即一个通道既可以用于读数据,又可以用于写数据。注意,这点不同于 I/O 中的 Stream,Stream 是单向的(只能是输入流或输出流)。
在 NIO 中,就是使用“缓冲区+通道”进行数据的传输。具体地讲,就是使用通道对缓冲区、文件或套接字进行数据传输。
可以把缓冲区理解为“池塘”,把通道理解为“排水管”。
NIO 中的 Channel(通道)是一个接口,有以下几种常见的实现类。
- FileChannel
- SocketChannel
- ServerSocketChannel
- DatagramChannel
如果药获取 Channel 对象,可以使用下表。
|
FileInputStream
FileOutputStream
RandomAccessFile
|
本地 I/O 类。这些类中都提供了 FileChannel getChannel() 方法,可以用于获取 FileChannel 对象。
|
|
Socket
ServerSocket
DatagramSocket
|
网络 I/O 类。这些类提供了 XXXChannel getChannel() 方法,可以用于获取不同类型的 Channel 对象。
|
|
FileChannel 等各个 Channel 实现类
|
Channel 实现类中,都提供了用于获取 Channel 对象的 open() 方法。例如,FileChannel 类中的 open() 方法:public static FileChannel open(Path path, OpenOption... options) throws IOException
|
|
Files
|
public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
|
二 缓冲区文件复制
1 代码
package nio;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.Pipe;
import java.nio.charset.CharacterCodingException;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public class NIODemo {
// 使用非直接缓冲区复制文件
public static void test2() throws IOException {
long start = System.currentTimeMillis();
FileInputStream input = new FileInputStream("g:\\navicat.chm");
FileOutputStream out = new FileOutputStream("g:\\navicat_copy1.chm");
// 获取通道
FileChannel inChannel = input.getChannel();
FileChannel outChannel = out.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inChannel.read(buffer) != -1) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
if (outChannel != null) outChannel.close();
if (inChannel != null) inChannel.close();
if (out != null) out.close();
if (input != null) input.close();
long end = System.currentTimeMillis();
System.out.println("复制操作消耗的时间(毫秒):" + (end - start));
}
// 使用直接缓冲区复制文件
public static void test2_2() throws IOException {
long start = System.currentTimeMillis();
FileInputStream input = new FileInputStream("g:\\navicat.chm");
FileOutputStream out = new FileOutputStream("g:\\navicat_copy2.chm");
// 获取通道
FileChannel inChannel = input.getChannel();
FileChannel outChannel = out.getChannel();
ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (inChannel.read(buffer) != -1) {
buffer.flip();
outChannel.write(buffer);
buffer.clear();
}
if (outChannel != null) outChannel.close();
if (inChannel != null) inChannel.close();
if (out != null) out.close();
if (input != null) input.close();
long end = System.currentTimeMillis();
System.out.println("复制操作消耗的时间(毫秒):" + (end - start));
}
public static void main(String[] args) throws IOException {
test2();
System.out.println("--------------------------");
test2_2();
}
}
2 测试
复制操作消耗的时间(毫秒):162
复制操作消耗的时间(毫秒):137