前言

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. [Big Data - Suro] Netflix开源数据流管理器Suro

    Netflix近日开源了一个叫做Suro的工具,公司可以利用它来做数据源主机到目标主机的实时定向.它不只在Netflix的数据管道上扮演重要角色,大规模下的应用场景同样令人印象深刻. Netflix各 ...

  2. linux每日命令(18):whereis命令

    whereis命令用于查找文件. 该指令会在特定目录中查找符合条件的文件.这些文件应属于原始代码.二进制文件,或是帮助文件. 该指令只能用于查找二进制文件.源代码文件和man手册页,一般文件的定位需使 ...

  3. js实现禁止pc端浏览器缩放和获取当前页面浏览器的缩放大小

    众所周知:移动端页面禁止用户缩放界面只需加上<meta name="viewport" content="user-scalable=0">即可,但 ...

  4. [NM]打开NetworkManager和wpa_supplicant的DEBUG接口

    turn on the DEBUG log in /etc/NetworkManager/NetworkManager.conf and restart NetworkManager. [loggin ...

  5. Eclipse使用心得与技巧

    一. 常用快捷键(熟练使用快捷键可以充分提高编程效率,吐血整理...) 1,Alt + ↑上方向键:向上移动选中的代码,你可以把一行或者一段代码直接上移几行 2,Alt + ↓下方向键:向下移动选中的 ...

  6. 卡通渲染Shader

    http://www.opengpu.org/forum.php?mod=viewthread&tid=17071http://www.opengpu.org/bbs/forum.php?mo ...

  7. 一种消息和任务队列——beanstalkd

    beanstalkd 是一个轻量级消息中间件,其主要特性: 基于管道  (tube) 和任务 (job) 的工作队列 (work-queue):d 管道(tube),tube类似于消息主题(topic ...

  8. 《精通Python网络爬虫》

    抓包工具 Fiddler 爬虫的浏览器伪装技术 Python Scrapy 框架

  9. python socket 实现的简单http服务器

    预备知识: 关于http 协议的基础请参考这里. 关于socket 基础函数请参考这里. 关于python 网络编程基础请参考这里. 一.python socket 实现的简单http服务器   废话 ...

  10. linux udev学习

    自2.6 核心开始,就可以使用udev 协助管理系统中各设备名称.例如,磁盘设备排序.网卡设备排序等.udev能动态地在/dev 目录里产生自定义的.标识性强的设备文件或设备链接.本文即以红旗Asia ...