1. 传统IO-面向流

1.1 基于字节的IO接口 In/OutputStream



1.2 基于字符的IO接口 Reader/Writer

Reader提供抽象方法: int read(char cbuf[], int off, int len)
Writer提供 int write(char cbuf[], int off, int len)



1.3 Java字符编码

1)内置部分字符集: StandardCharsets.UTF_8
2)只有当从外部引入byte[]或向外部输出byte[]时才需要指定编码。如socket、file操作等! //编码转换,字符省略时默认'utf-8'
new String(ss.getBytes("UTF-8"), StandardCharsets.UTF_8); Charset charset = Charset.forName(StandardCharsets.UTF_8);
ByteBuffer byteBuffer = charset.encode(string);
CharBuffer charBuffer = charset.decode(byteBuffer);
//当前运行时的字符集
Charset.defaultCharset().displayName();
//是否支持字符集
Charset.isSupported("gbk");
//当前支持的所有字符集
Set<String> charsetNames = Charset.availableCharsets().keySet();

2 NIO-面向缓冲

2.0 Files 文件操作

	Files.exists()		//文件是否存在
Files.createDirectory() //创建[多级]目录
Files.createDirectories(newPath);
Files.copy() //可覆盖
Files.move()
Files.delete()
Files.readAttributes(path, "*") //获取文件属性
Files.isDirectory() //文件类型,是否文件夹 path.getParent().toString() //文件所在目录
path.toString() //文件全路径
path.toFile().getName() //获取文件名 List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8); //读文件
byte[] bytes = Files.readAllBytes(path); //读文件
Files.lines(path, StandardCharsets.UTF_8).forEach((line) -> { //读文件
System.out.println(line);
}); //写文件
try(BufferedWriter writer = Files.newBufferedWriter(path, StandardCharsets.UTF_8, StandardOpenOption.WRITE)){
writer.write("Hello World!");
} //二进制读写文件
InputStream in = new FileInputStream("myfile//a.txt");//("myfile//a.txt",true)
x[i] = (char)in.read(); OutputStream out = new FileOutputStream("b.txt");
out.write(bytes, 0, bytes.length);
	//递归遍历文件
Files.walkFileTree();
public static void main(String[] args) throws IOException
{
Path path = Paths.get("F:/project/C10/20160704-");
Files.walkFileTree(path, new findPropertyVisitor());
}
private static class findPropertyVisitor extends SimpleFileVisitor<Path>{
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attributes){
if(file.toString().endsWith(".properties")){
System.out.println(file.getFileName());
}
return FileVisitResult.CONTINUE; //其它选项
}
}

2.1 Path 位置/路径

注:1)Path可独立存在,只有在读取或写入时才会异常
2) 去掉./..-->path.normalize() ,快捷方式的真实地址:path.toRealPath()
Path listing = Paths.get("C:/Users/z00316474/Desktop");

2.2 Channel: data<->Buffer<->Channel

FileChannel
DatagramChannel
SocketChannel
ServerSocketChannel

2.2.1 FileChannel 文件通道

a). 连接到文件的通道。可以通过文件通道读写文件,总是运行在阻塞模式下。
b). 无法直接打开一个FileChannel,需要通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例 FileChannel.tranferTo() //从源channel获取数据到当前channel ,数据直接在内核空间移动,减少系统调用切换
FileChannel.tranferTo() //从当前channel数据传输到其它channel
FileChannel.map 将文件按照一定大小映射为内存区域,适合对大文件的只读性操
 RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48); int bytesRead = inChannel.read(buf); //读文件
//因为无法保证write()方法一次能向FileChannel写入多少字节,因此需要重复调用write()方法
channel.write(buf); //写文件
channel.close(); //关闭 channel.position(pos +123); //设置文件指针的位置
channle.size() //文件大小
channel.truncate(1024); //截取文件前1024字节,后面将被删除
channel.force(true); //强制写文件到磁盘

2.2.2 SocketChannel -TCP Client

SocketChannel socketChannel = SocketChannel.open();		//打开
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80)); socketChannel.close(); //关闭 ByteBuffer buf = ByteBuffer.allocate(48); //读数据
int bytesRead = socketChannel.read(buf); while(buf.hasRemaining()) { //写入数据
channel.write(buf);
}

2.2.3 ServerSocketChannel - TCP Server

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(9999));
while(true){
SocketChannel socketChannel = serverSocketChannel.accept();
}

2.2.4 DatagramChannel UDP

DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(9999));
ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
channel.receive(buf);
int bytesSent = channel.send(buf, new InetSocketAddress("jenkov.com", 80));

2.3 Buffer缓冲区,data<->Buffer<->Channel

本质上是一块可以写入数据,然后可以从中读取数据的内存,以下3个重要属性:
capacity 缓冲区数组的总长度
position 下一个可读写的位置
limit 不可操作的下一个元素的位置,写-还能写多少数据,读-==capacity
mark 用于记录当前 position 的前一个位置或者默认是 0
//类型
ByteBuffer ;MappedByteBuffer; CharBuffer;DoubleBuffer; FloatBuffer; IntBuffer; LongBuffer;ShortBuffer; //使用步骤
将数据写入到 Buffer 中.
调用 Buffer.flip()方法, 将 NIO Buffer 转换为读模式.
从 Buffer 中读取数据
调用 Buffer.clear() 或 Buffer.compact()方法, 将 Buffer 转换为写模式
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel(); ByteBuffer buf = ByteBuffer.allocate(48); //分配空间
int bytesRead = inChannel.read(buf); //读数据到buffe中
while (bytesRead != -1) {
buf.flip(); //flip方法将Buffer从写模式切换到读模式。调用flip()方法会将position设回0,并将limit设置成之前position的值
while(buf.hasRemaining()){
System.out.print((char) buf.get()); // 从buffer中取数据
}
buf.clear(); //position将被设回0,limit被设置成 capacity的值。数据未清除,只是标记从哪里开始写数据
bytesRead = inChannel.read(buf);
}
mark()与reset()方法		mark()标记Buffer中的一个特定position。之后调用Buffer.reset()方法恢复到这个position。
equals() 只比较剩余元素,同时满足以下条件则true
a).有相同的类型(byte、char、int等)。
b).Buffer中剩余的byte、char等的个数相等。
c).Buffer中所有剩余的byte、char等都相同
compareTo() 比较两个Buffer的剩余元素(byte、char等), 如果满足下列条件,则认为一个Buffer“小于”另一个Buffer
a).第一个不相等的元素小于另一个Buffer中对应的元素 。
b).所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)

2.4 Selector-阻塞多个channel直到事件触发

a). 一个单独的线程可以管理多个channel,从而管理多个网络连接。
b). 向Selector注册Channel,然后调用它的select()方法 //创建
Selector selector = Selector.open(); //注册,与Selector一起使用时,Channel必须处于非阻塞模式下,返回SelectionKey对象(包含Channel、selector、ready集合、interest集合)
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, Selectionkey.OP_READ); //其它可选:OP_WRITE-写事件,OP_CONNECT,OP_ACCEPT //监控,一旦调用将阻塞直到有注册事件触发
selector.select(); //返回值表示自上次调用select()方法后有多少通道变成就绪状态 //获取触发的selectionKey对象
Set selectedKeys = selector.selectedKeys(); //触发的事件,事件类型判断
int readySet = selectionKey.readyOps();
selectionKey.isAcceptable();
selectionKey.isConnectable();
selectionKey.isReadable();
selectionKey.isWritable(); //关闭,关闭该Selector,且使注册到该Selector上的所有SelectionKey实例无效,通道本身并不会关闭
selector.close()
//实例代码
Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
while(true) {
int readyChannels = selector.select();
if(readyChannels == 0) continue;
Set selectedKeys = selector.selectedKeys();
Iterator keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
} else if (key.isConnectable()) {
// a connection was established with a remote server.
} else if (key.isReadable()) {
// a channel is ready for reading
} else if (key.isWritable()) {
// a channel is ready for writing
}
keyIterator.remove();
}
}

try-with-resource 资源自动关闭

实现了Closeable接口的类
1)try后面()中打开的资源会在{}代码执行完成/异常后自动关闭
2) 可结合catch、finally使用,在资源关闭后执行
try (
java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {}

java NIO-java.io的更多相关文章

  1. java nio 与io区别

    转自:http://blog.csdn.net/keda8997110/article/details/19549493 当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使 ...

  2. Java NIO和IO的主要区别

    From :http://blog.csdn.net/keda8997110/article/details/19549493 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部 ...

  3. Java NIO 和 IO 的区别详解

    Java NIO为jdk1.4提供了新的API,本文主要来比较一下Java中NIO和IO的区别,Java初学者可以了解一下. 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分 ...

  4. Java NIO与IO

    当学习了Java NIO和IO的API后,一个问题立即涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们怎样影响您的代 ...

  5. Java NIO 与 IO

    我应该何时使用 IO,何时使用 NIO 呢?在本文中,我会尽量清晰地解析 Java NIO 和 IO 的差异.它们的使用场景,以及它们如何影响您的代码设计. Java NIO 和 IO 的主要区别 下 ...

  6. [转载] Java NIO与IO

    原文地址:http://tutorials.jenkov.com/java-nio/nio-vs-io.html 作者:Jakob Jenkov   译者:郭蕾    校对:方腾飞 当学习了Java ...

  7. Java NIO系列教程(十二) Java NIO与IO

    当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...

  8. Java NIO和IO的区别(转)

    原文链接:Java NIO和IO的区别 下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异. 复制代码代码如下: IO                NIO面向流     ...

  9. Java NIO系列教程(十一) Java NIO 与 IO

    Java NIO系列教程(十一) Java NIO与IO 当学习了 Java NIO 和 IO 的 API 后,一个问题马上涌入脑海: 我应该何时使用 IO,何时使用 NIO 呢?在本文中,我会尽量清 ...

  10. Java NIO:IO与NIO的区别 -阿里面试题

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

随机推荐

  1. 【转】 Pro Android学习笔记(二七):用户界面和控制(15):FrameLayout

    FrameLayout FrameLayout通常只包含一个控件.如果我们在FrameLayout中设置多个控件,则第二个控件会堆叠在第一个控件上面,如此类推,一层一层地叠上去.下面的例子,我们在Fr ...

  2. 集群重启某一主机下所有osd down解决办法

    标签(空格分隔): ceph 运维 osd 问题描述: 掉电后,上电发现cluster中的主机node3下的所有osd都down掉了,通过命令重启node3的ceph-osd服务,osd依然无法up: ...

  3. Math类简介

    Math  abs max min 分别是绝对值 最大值,最小值 round 四舍五入 ceil ceil(32.6)  33.0 ceil(32.2) 33.0 返回大于该数值的较大的整数 与之相对 ...

  4. mysql主从服务器复制原理

    在实际企业应用环境当中,单台mysql数据库是不足以满足日后业务需求的.譬如服务器发生故障,没有备份服务器来提供服务的话,业务就得停止.介于这种情况,我们来学习一下mysql主从复制. 将Mysql的 ...

  5. http相关理解

    http://blog.csdn.net/generon/article/details/73920945

  6. 【创建maven-web项目-eclipse-jee-mars-2-win32-x86_64-jdk1.8】

    需要注意的是:创建的mavenweb项目是没有java源文件夹的需要手动添加: 创建项目完成以后,项目会报错,如下: 因为项目中没有添加servlet依赖解决jsp报错问题:添加依赖: <dep ...

  7. C# 关于跨线程访问控件问题

    跨线程访问控件问题的原因是:控件都是在主线程中创建的,而系统默认控件的修改权归其创建线程所有.在子线程中如果需要直接修改控件的内容,需要使用委托机制将控件的修改操作交给主线程处理.因此,当没有使用委托 ...

  8. 浅析C#中的事件

    讲过了委托,不得不讲事件. 事件基于委托,为委托提供了一种发布/订阅机制. 在发生其他类或对象关注的事情时,类或对象可通过事件通知它们.发送(或引发)事件的类称为“发行者”,接收(或处理)事件的类称为 ...

  9. C# 写 LeetCode easy #21 Merge Two Sorted Lists

    21. Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new list s ...

  10. java线程基础知识----SecurityManager类详解

    在查看java Thread源码的时候发现一个类----securityManager,虽然很早就知道存在这样一个类但是都没有深究,今天查看了它的api和源码,发现这个类功能强大,可以做很多权限控制策 ...