java NIO模型,三大核心原理,不防来看看( 二 )

(4)案例2-本地文件读数据
public class NIOFileChannel02 {
public static void main(String[] args) throws Exception {
//创建文件的输入流
File file = new File("/Users/apple/学习/study/test01.txt");
FileInputStream fileInputStream = new FileInputStream(file);
//通过fileInputStream 获取对应的FileChannel -> 实际类型 FileChannelImpl
FileChannel fileChannel = fileInputStream.getChannel();
//创建缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
//将通道的数据读入到Buffer
fileChannel.read(byteBuffer);
?
//将byteBuffer 的 字节数据 转成String
System.out.println(new String(byteBuffer.array()));
fileInputStream.close();
?
}
}
(5)案例3-使用Buffer完成文件的读取、写入
public class NIOFileChannel03 {
public static void main(String[] args) throws Exception {
?
FileInputStream fileInputStream = new FileInputStream("1.txt");
FileChannel fileChannel01 = fileInputStream.getChannel();
?
FileOutputStream fileOutputStream = new FileOutputStream("2.txt");
FileChannel fileChannel02 = fileOutputStream.getChannel();
?
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
?
//循环读取
while (true) {
?
//这里有一个重要的操作,一定不要忘了
/*
public final Buffer clear() {
position = 0;
limit = capacity;
mark = -1;
return this;
}
*/
byteBuffer.clear(); //清空buffer
int read = fileChannel01.read(byteBuffer);
System.out.println("read =" + read);
//表示读完
if (read == -1) {
break;
}
//将buffer 中的数据写入到 fileChannel02 -- 2.txt
byteBuffer.flip();
fileChannel02.write(byteBuffer);
}
?
//关闭相关的流
fileInputStream.close();
fileOutputStream.close();
}
}
(6)案例4-拷贝文件 transferFrom 方法
public class NIOFileChannel04 {
public static void main(String[] args) throws Exception {
?
//创建相关流
FileInputStream fileInputStream = new FileInputStream("a.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("a1.jpg");
?
//获取各个流对应的fileChannel
FileChannel sourceCh = fileInputStream.getChannel();
FileChannel destCh = fileOutputStream.getChannel();
?
//使用transferForm完成拷贝
destCh.transferFrom(sourceCh,0,sourceCh.size());
//关闭相关通道和流
sourceCh.close();
destCh.close();
fileInputStream.close();
fileOutputStream.close();
}
}
(7)案例5-零拷贝文件-transferTo文件
零拷贝参考资料:
https://www.cnblogs.com/yibutian/p/9482640.html
http://www.360doc.com/content/19/0528/13/99071_838741319.shtml
public class NewIOClient {
public static void main(String[] args) throws Exception {
String filename = "/Users/apple/password.txt";
?
//得到一个文件channel
FileChannel fileChannel = new FileInputStream(filename).getChannel();
FileChannel fileChannel1 = new FileOutputStream("/Users/apple/password1.txt").getChannel();
?
//准备发送
long startTime = System.currentTimeMillis();
?
//在linux下一个transferTo 方法就可以完成传输
//在windows 下 一次调用 transferTo 只能发送8m,就需要分段传输文件
//transferTo 底层使用到零拷贝
long transferCount = fileChannel.transferTo(0, fileChannel.size(), fileChannel1);
?
System.out.println("发送的总的字节数 =" + transferCount + " 耗时:" + (System.currentTimeMillis() - startTime));
?
//关闭
fileChannel.close();
?
}
}
?
(8)注意事项和细节
1)ByteBuffer 支持类型化的 put 和 get, put 放入的是什么数据类型,get 就应该使用相应的数据类型来取出,否则可能有 BufferUnderflowException 异常
public class NIOByteBufferPutGet {
public static void main(String[] args) {
? //创建一个Buffer
ByteBuffer buffer = ByteBuffer.allocate(64);
?
//类型化方式放入数据
buffer.putInt(100);
buffer.putLong(9);
buffer.putChar('a');
buffer.putShort((short) 4);
?
//取出
buffer.flip();
?
System.out.println();
?
System.out.println(buffer.getInt());
System.out.println(buffer.getLong());
System.out.println(buffer.getChar());
System.out.println(buffer.getLong());
}
}
2)可以将一个普通Buffer转成只读Buffer
public class ReadOnlyBuffer {


推荐阅读