前言

Java NIO(new/inputstream outputstream)使用通道、缓冲来操作流,所以要深刻理解这些概念,尤其是,缓冲中的数据结构(当前位置(position)、限制(limit)、容量(capacity)),这些知识点要通过写程序慢慢体会。

NIO vs  传统IO

NIO是面向缓冲、通道的;传统IO面向流

通道是双向的既可以写、也可以读;传统IO只能是单向的

NIO可以设置为异步;传统IO只能是阻塞,同步的

缓冲区结构图

NIO是面向缓冲区的,缓冲区可以理解为一块内存,有大小。缓冲区有位置、界限、容量几个概念。

capacity:容量,缓冲区的大小

limit:限制,表示最大的可读写的数量

position:当前位置,每当读写,当前位置都会加一

flip和clear方法,内部就操作这三个变量。

缓冲区常用方法

clear:将当前位置设置为0,限制设置为容量,目的是尽最大可能让字节,由通道读取到缓冲中

flip:当前位置置为限制,然后将当前位置置为0,目的是将有数据部分的字节,由缓冲写入到通道中。通常用在读与写之间。

读写文件代码

 package com.nio;

 import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset; public class TestJavaNio { public static String pathname = "d://read.txt";
public static String filename = "d://write.txt"; @SuppressWarnings("resource")
public static void main(String[] args) {
readNIO();
writeNIO();
//testReadAndWriteNIO();
} public static void readNIO() {
FileInputStream fin = null;
try {
fin = new FileInputStream(new File(pathname));
FileChannel channel = fin.getChannel(); int capacity = 1000;// 字节
ByteBuffer bf = ByteBuffer.allocate(capacity);
System.out.println("限制是:" + bf.limit() + ",容量是:" + bf.capacity() + " ,位置是:" + bf.position());
int length = -1; while ((length = channel.read(bf)) != -1) { /*
* 注意,读取后,将位置置为0,将limit置为容量, 以备下次读入到字节缓冲中,从0开始存储
*/
bf.clear();
byte[] bytes = bf.array();
System.out.println("start.............."); String str = new String(bytes, 0, length);
System.out.println(str);
//System.out.write(bytes, 0, length); System.out.println("end................"); System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position()); } channel.close(); } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void writeNIO() {
FileOutputStream fos = null;
try { fos = new FileOutputStream(new File(filename));
FileChannel channel = fos.getChannel();
ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");
// 字节缓冲的容量和limit会随着数据长度变化,不是固定不变的
System.out.println("初始化容量和limit:" + src.capacity() + ","
+ src.limit());
int length = 0; while ((length = channel.write(src)) != 0) {
/*
* 注意,这里不需要clear,将缓冲中的数据写入到通道中后 第二次接着上一次的顺序往下读
*/
System.out.println("写入长度:" + length);
} } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void testReadAndWriteNIO() {
FileInputStream fin = null;
FileOutputStream fos = null;
try {
fin = new FileInputStream(new File(pathname));
FileChannel channel = fin.getChannel(); int capacity = 100;// 字节
ByteBuffer bf = ByteBuffer.allocate(capacity);
System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity() + "位置是:" + bf.position());
int length = -1; fos = new FileOutputStream(new File(filename));
FileChannel outchannel = fos.getChannel(); while ((length = channel.read(bf)) != -1) { //将当前位置置为limit,然后设置当前位置为0,也就是从0到limit这块,都写入到同道中
bf.flip(); int outlength = 0;
while ((outlength = outchannel.write(bf)) != 0) {
System.out.println("读," + length + "写," + outlength);
} //将当前位置置为0,然后设置limit为容量,也就是从0到limit(容量)这块,
//都可以利用,通道读取的数据存储到
//0到limit这块
bf.clear(); }
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} }

Java NIO 读取文件、写入文件、读取写入混合的更多相关文章

  1. JAVA NIO FileChannel 内存映射文件

      文件通道总是阻塞式的. 文件通道不能创建,只能通过(RandomAccessFile.FileInputStream.FileOutputStream)getChannel()获得,具有与File ...

  2. Java NIO之内存映射文件——MappedByteBuffer

    大多数操作系统都可以利用虚拟内存实现将一个文件或者文件的一部分"映射"到内存中.然后,这个文件就可以当作是内存数组来访问,这比传统的文件要快得多. 内存映射文件的一个关键优势是操作 ...

  3. Java IO和Java NIO 和通道 在文件拷贝上的性能差异分析

    1.  在JAVA传统的IO系统中,读取磁盘文件数据的过程如下: 以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区 ...

  4. java nio通过ByteBuffer输出文件信息

    1.通过ByteBuffer的get()方法每次读取一个字节转换成char类型输出. fc = new FileInputStream("src/demo20/data.txt") ...

  5. Java NIO FileVisitor 高效删除文件

    在公司项目中,由于做个二维码扫码平台项目,预计每天产生的二维码图片达到十几G,所以要做个定时清理任务来定时清理图片,根据不同场景保留图片,规则是:1.二维码统一登录图片几个小时有效   2.电子名片二 ...

  6. Java NIO(四)文件通道

    文件通道 通道是访问I/O服务的导管,I/O可以分为广义的两大类:File I/O和Stream I/O.那么相应的,通道也有两种类型,它们是文件(File)通道和套接字(Socket)通道.文件通道 ...

  7. java nio 快速read大文件

    If you want to make your first example faster FileChannel inChannel = new FileInputStream(fileName). ...

  8. Java NIO学习笔记五 FileChannel(文件通道)

    Java NIO FileChannel Java NIO FileChannel是连接文件的通道.使用FileChannel,您可以从文件中读取数据和将数据写入文件.Java NIO FileCha ...

  9. Java NIO 完全学习笔记(转)

    本篇博客依照 Java NIO Tutorial翻译,算是学习 Java NIO 的一个读书笔记.建议大家可以去阅读原文,相信你肯定会受益良多. 1. Java NIO Tutorial Java N ...

  10. Java NIO 进程间通信

    转自:http://blog.csdn.net/lingzhm/article/details/45026119 传统的进程间通信的方式有大致如下几种: (1)   管道(PIPE) (2)   命名 ...

随机推荐

  1. 编写SHELL脚本--编写简单脚本

    1.简单脚本文件hello.sh,内容如下 #!/bin/bash pwd ls -al 执行脚本:bash hello.sh  或者使用root命令:  ./hello.sh 2.接受用户参数 $0 ...

  2. android 获得View的高度

      在一个activity中有一个textview,设置字数不同,如何能在打开这个activity时就及时获得这个textview在activity的高度,有利于我对textview的高度进行设置. ...

  3. Mybatis 记录

    1. #{}, ${}两种传参数方式的区别 1) ${} 会将传入的参数完全拼接到sql语句中,也就是相当于一个拼接符号. 也就是,最后的处理方式就相当于 String sql = select * ...

  4. mysql 物理数据存放

    报错误:1030 - Got error 28 from storage engine 3.在系统中查看/tmp是否已经满了: [root@localhost /]# df /tmp/ Filesys ...

  5. 第三部分:Android 应用程序接口指南---第一节:应用程序组件---第一章1-1.Fragment

    第1-1章 Fragments 在Activity中的fragment代表的是一种行为或用户界面的一部分.你可以在activity中结合多个fragments创建一个多面板UI,并可以在多个activ ...

  6. TEST DESIGN TECHNIQUES: AN OVERVIEW

    TEST DESIGN TECHNIQUES: AN OVERVIEW -Test note of “Essential Software Test Design” 2015-11-16 目录: 7. ...

  7. 在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求(转)

    通用辅助类 下面是我编写的一个辅助类,在这个类中采用了HttpWebRequest中发送GET/HTTP/HTTPS请求,因为有的时候需要获取认证信息(如Cookie),所以返回的是HttpWebRe ...

  8. Android Gallery实现3D相册(附效果图+Demo源码)

    今天因为要做一个设置开机画面的功能,主要是让用户可以设置自己的开机画面,应用层需要做让用户选择开机画面图片的功能.所以需要做一个简单的图片浏览选择程序.最后选用Gallery作为基本控件.加入了一些炫 ...

  9. [备份]EntityFramework

    本视频和分步演练介绍通过 Code First 开发建立新数据库.这个方案包括建立不存在的数据库(Code First 创建)或者空数据库(Code First 向它添加新表).借助 Code Fir ...

  10. JDK8+Tomcat8配置https【转】

    生成密钥对 我比较喜欢密钥对这个名字,因为它非常明确了HTTPS在传输过程中需要的两个钥匙(公钥和私钥).如果不太了解HTTPS的,可以要到搜索引擎去搜索一下HTTPS的原理. 首先,确保java的目 ...