JAVA NIO中的一些主要Channel的实现:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
1.1:FileChannel基本使用
Java NIO中的FileChannel是一个连接到文件的通道。可以通过文件通道读写文件。
FileChannel无法设置为非阻塞模式,它总是运行在阻塞模式下。
1.1.1创建FileChannel
在使用FileChannel之前,必须先创建它。创建方式有两种:
第一种:使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例。
第二种:JDK1.7之后才能使用, FileChannel.open()方法。
//第一种
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
//第二种
FileChannel inChannel = FileChannel.open(Paths.get("d:\\aaa.txt"),StandardOpenOption.READ);
1.1.从FileChannel读取数据
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
首先,分配一个Buffer。从FileChannel中读取的数据==将被读到Buffer中。将被 还没有读到缓冲区里面
然后,调用FileChannel.read()方法。该方法将数据从FileChannel读取(实际是将通道从文件读取的数据写入缓冲区,因此要从缓冲区取数据的时候需要将缓冲区从写模式转换成读取模式)到Buffer中。read()方法返回的int值表示了有多少字节被读到了Buffer中。如果返回-1或者0,表示到了文件末尾。
==读取文本文件==
public class ChannelTest {
public static void main(String[] args) throws IOException {
//创建FileChannel,指定要读取的文件
FileChannel channel = FileChannel.open(Paths.get("aaa.txt"), StandardOpenOption.READ);
ByteBuffer buffer=ByteBuffer.allocate(1024);//创建缓冲区
while (channel.read(buffer)>0){//将channel从文件中读取的数据写入到缓冲区中。到尽头时候为0或者-1
//buffer改为读取模式
buffer.flip();
String s = new String(buffer.array(), 0, buffer.limit());//从缓冲区中读取数据
System.out.println(s);
buffer.clear();
}
channel.close();
}
}
1.1.从FileChannel写数据
使用FileChannel.write()方法向FileChannel写数据,该方法的参数是一个Buffer。
先将写的字符串转换成字节,然后用put方法将数据放入缓冲区,再将缓冲区转成读取模式,读取缓冲区中的数据写入到通道中(即硬盘);
如:
String newData = "New String to write to file..." + System.currentTimeMillis();
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();
channel.write(buf);
==写到指定文件==
//从从FileChannel写数据到指定文件
public class ChannelTest2 {
public static void main(String[] args) throws Exception {
FileChannel channel=FileChannel.open(Paths.get("ccc.txt"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
ByteBuffer buffer=ByteBuffer.allocate(1024);
buffer.put("你好吗aaa".getBytes());
buffer.flip();
channel.write(buffer);
channel.close();
}
}
*1.1.复制图片
即一边读取一遍写入
注意:清空缓冲区不会把数据清空只是opsiton位置指针归零,limit限制到缓冲区尾,再次写入到到缓冲区世区时,写入多少,limit会移动到写入位置,从缓冲区再次读取只能读到limit位置不用担心读到上次缓冲区残留数据*
public class Copy {
public static void main(String[] args) throws Exception {
FileChannel readchannel=FileChannel.open(Paths.get("aaa.png"), StandardOpenOption.READ);
FileChannel writechannel=FileChannel.open(Paths.get("bbb.png"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);//创建写入的channel,并指定没有文件时候创建该文件并写入
ByteBuffer buffer=ByteBuffer.allocate(1024);
while (readchannel.read(buffer)>0){//**清空缓冲区不会把数据清空只是opsiton位置指针归零,limit限制到缓冲区尾,再次写入到到缓冲区世区时,写入多少,limit会移动到写入位置,从缓冲区再次读取只能读到limit位置不用担心读到上次缓冲区残留数据**
buffer.flip();
writechannel.write(buffer);
buffer.clear();//清空缓冲区 便于下次读取数据
}
readchannel.close();
writechannel.close();
}
}