FileChannel

FileChannel是什么

FileChannel是一个连接到文件的通道,可以通过文件通道读写文件。它无法设置为非阻塞模式,总是运行在阻塞模式下。

打开FileChannel

我们可以通过使用一个InputStream、OutputStream或RandomAccessFile来获取一个FileChannel实例。例如:

RandomAccessFile aFile = new RandomAccessFile("D:/demo/data.txt", "rw");
FileChannel inChannel = aFile.getChannel();

读FileChannel

调用FileChannel.read()方法,例如:

ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);

read()方法返回的int值表示了有多少字节被读到了Buffer中。如果返回-1,表示到了文件末尾。

写FileChannel

调用FileChannel.write()方法,例如:

String newData = "Some data";ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();while(buf.hasRemaining()) {channel.write(buf);
}

因为无法保证write()方法一次能向FileChannel写入多少字节,因此需要重复调用write()方法,直到Buffer中已经没有尚未写入通道的字节。

关闭FileChannel

用完FileChannel后必须将其关闭,例如:

channel.close();

FileChannel的位置

调用position()方法可以获取FileChannel的当前位置,调用position(long pos)方法设置FileChannel的当前位置。例如:

long pos = channel.position();
channel.position(pos + 100);

如果将位置设置在文件结束符之后,然后从通道中读数据,读方法将返回-1 ,也就是文件结束标志。 
如果将位置设置在文件结束符之后,然后向通道中写数据,文件将撑大到当前位置并写入数据。这可能导致“文件空洞”,磁盘上物理文件中写入的数据间有空隙。

获取文件的大小

long fileSize = channel.size();

截取文件

调用FileChannel.truncate()方法,截取文件时,文件中指定长度后面的部分将被删除。如:

channel.truncate(1024);

强制写入磁盘

操作系统一般会将数据缓存在内存中,写入到FileChannel里的数据不一定会即时写到磁盘上。调用force()方法可以将通道里尚未写入磁盘的数据强制写到磁盘上。 
force()方法有一个boolean类型的参数,true表示同时将文件元数据(权限信息等)写到磁盘上,例如:

channel.force(true);

SocketChannel

SocketChannel是什么

SocketChannel是一个连接到TCP网络套接字的通道。

打开 SocketChannel

SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://www.xxx.com", 80));

关闭 SocketChannel

socketChannel.close();

读SocketChannel

同读FileChannel。

写SocketChannel

同写FileChannel。

非阻塞模式下的连接

非阻塞模式下调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()方法。

socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://www.xxx.com", 80));while(!socketChannel.finishConnect() ){// wait, or do something else
}

非阻塞模式下的读

非阻塞模式下,read()方法在尚未读到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。

非阻塞模式下的写

非阻塞模式下,write()方法在尚未写出任何数据时可能就返回了。所以需要在循环中调用write()。

ServerSocketChannel

ServerSocketChannel是什么

ServerSocketChannel 是一个可以监听新进来的TCP连接的通道,就像标准IO中的ServerSocket一样。

打开 ServerSocketChannel

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

关闭 ServerSocketChannel

serverSocketChannel.close();

监听新进来的连接

用ServerSocketChannel.accept()方法监听新进来的连接。当 accept()方法返回的时候,它返回一个包含新进来的连接的 SocketChannel。因此,accept()方法会一直阻塞到有新连接到达。

while(true){SocketChannel socketChannel = serverSocketChannel.accept();// do something
}

如果是非阻塞模式,accept()方法会立刻返回,如果还没有新进来的连接,返回的将是null。 因此,需要检查返回的SocketChannel是否是null.

ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.socket().bind(new InetSocketAddress(80));
serverSocketChannel.configureBlocking(false);while(true) {SocketChannel socketChannel = serverSocketChannel.accept();if (socketChannel != null) {//do something}
}

DatagramChannel

DatagramChannel是什么

DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。

打开 DatagramChannel

DatagramChannel channel = DatagramChannel.open();
channel.socket().bind(new InetSocketAddress(9000));

接收数据

ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
channel.receive(buf);

发送数据

String newData = "Some data";ByteBuffer buf = ByteBuffer.allocate(48);
buf.clear();
buf.put(newData.getBytes());
buf.flip();int bytesSent = channel.send(buf, new InetSocketAddress("www.xxx.com", 9000));

连接

由于UDP是无连接的,连接到特定地址并不会像TCP通道那样创建一个真正的连接,而是锁住DatagramChannel ,让其只能从特定地址收发数据。

channel.connect(new InetSocketAddress("www.xxx.com", 9000));

当连接后,也可以使用read()和write()方法,就像在用传统的通道一样,只是在数据传送方面没有任何保证。

Java NIO学习笔记三------Chanel的四种实现篇相关推荐

  1. Java NIO学习笔记 三 散点/收集 和频道转换

    Java NIO散点/收集 Java NIO带有内置的分散/收集支持.散点/收集是读取和写入渠道过程中使用的概念. 从通道散射读取是将数据读入多个缓冲区的读取操作.因此,数据可以从通道"散布 ...

  2. Java NIO 学习笔记(三)----Selector

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  3. Java NIO 学习笔记(五)----路径、文件和管道 Path/Files/Pipe

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  4. Java NIO学习笔记之图解ByteBuffer

    转载自 Java NIO学习笔记之图解ByteBuffer ByteBuffer前前后后看过好几次了,实际使用也用了一些,总觉得条理不够清晰. <程序员的思维修炼>一本书讲过,主动学习,要 ...

  5. 【Java基础学习笔记】- Day11 - 第四章 引用类型用法总结

    Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 Java基础学习笔记 - Day11 - 第四章 引用类型用法总结 4.1 class作为成员变量 4.2 interface作为成 ...

  6. Java NIO学习系列三:Selector

    前面的两篇文章中总结了Java NIO中的两大基础组件Buffer和Channel的相关知识点,在NIO中都是通过Channel和Buffer的协作来读写数据的,在这个基础上通过selector来协调 ...

  7. Java nio 学习笔记 相关知识

    http://blog.csdn.net/tsyj810883979/article/details/6876594 一.基本概念 IO 是主存和外部设备 ( 硬盘.终端和网络等 ) 拷贝数据的过程. ...

  8. Java基础学习笔记(三)_Java核心技术(高阶)

    本篇文章的学习资源来自Java学习视频教程:Java核心技术(高阶)_华东师范大学_中国大学MOOC(慕课) 本篇文章的学习笔记即是对Java核心技术课程的总结,也是对自己学习的总结 文章目录 Jav ...

  9. Java NIO学习笔记

    印象中,我对于NIO的学习,最早是来源于一次面试,面试官问我:"可不可以讲一下Netty的线程模型?".当然了,这个问题没答上来,于是回去后就开始搜Netty的资料,了解Netty ...

最新文章

  1. 《算法入门经典大赛——培训指南》第二章考试
  2. 引入extThree20JSON之后,怎么在工程中使用
  3. 7-8 连续因子 (20 分)
  4. Laravel核心解读--Database(四) 模型关联
  5. JVM 问题排查常用命令
  6. 2步判断晶体管工作状态
  7. element form 变 table
  8. Docker学习--基本docker命令
  9. idea 开源项目申请地址
  10. java IO 测试题
  11. 可视化编辑json数据——json editor
  12. “Master”围棋对战50胜1和,人工智能身份欲揭?
  13. Java 打印某年某月的月日历
  14. 4k hidpi 黑苹果_关于4K,1440P显示屏开启HIdpi的问题
  15. stm32 常见错误之can线通信
  16. JAVA初学者:适合小白的Java培训学习路线
  17. 基于Python实现的合同管理系统设计
  18. 这款游戏可能是minecraft和迷你世界的共同敌人了吧!
  19. ssm(spring mvc+mybatis)+netty4开发qiq
  20. Leetcode 1628. Design an Expression Tree With Evaluate Function [Python]

热门文章

  1. 全面揭秘快手与抖音的内容推荐算法
  2. 一个2803引发的血案
  3. Java图形类的实现
  4. 10-ext2 文件系统
  5. 解决Mac安装和删除windows系统,出现问题:无法合并分区
  6. 测试成长小说3 业务点点点真没意思
  7. java基础面试题题库三(传智专修学院2017级Java4班)
  8. 51单片机独立按键数码管可调时钟显示程序
  9. redhat 9.0 制作openssh rpm包(9.0p1/9.1/9.2/9.3 p1) —— 筑梦之路
  10. 漫漫长假,我独自在行走——记国庆长假