Java NIO入门
NIO入门
前段时间在公司里处理一些大的数据,并对其进行分词、提取关键字等。虽说任务基本完成了(效果也不是特别好),对于Java还没入门的我来说前前后后花了2周的时间,我自己也是醉了。当然也有涉及到机器学习的知识,我想陆陆续续的记录下我的这一次任务的过程,也算做一个总结。
首先,手上有这么个达G级别的文件,按照Java普通I/O的方式肯定是不行的了,划分文件的话,也不知何年何月才能读完。所以后来上网查找了相关资料,才知道有这么个神奇的NIO。
在Java编程中,I/O是用流的方式读取文件,所有I/O都被视为单个的字节的移动,通过一个称为Stream的对象一次移动一个字节。Java中新的输入/输出(NIO)库是在JDK1.4中引入的。NIO弥补了原来I/O的不足,它在标准Java代码中提供了高速、面向块的I/O。通过定义包含数据的块,以及通过以块的形式来处理这些数据,NIO不用使用本机代码就可以利用低级优化,这是原来的I/O包所无法做到的。
流与块的比较
原来的I/O库和NIO最重要的区别就是数据打包和传输的方式,原来的I/O以流的方式处理数据,而NIO以块的方式处理数据。
面向流的I/O系统一次一个字节的处理数据,一个输入流产生一个字节的数据,一个输出流产生一个字节的数据。
一个面向块的I/O系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按字节处理数据要快得多,即便它没有面向流的I/O那样的简单性。
通道和缓冲区
通道和缓冲区是NIO中的核心对象,几乎在每一个I/O操作中都要使用它们。
通道是对原I/O包中的流的模拟。到任何目的地或来自任何地方的所有数据都必须通过一个Channel对象。一个Buffer实质上是一个容器对象。发送给一个通道的所有对象都必须首先存放到缓冲区中;同样的,从通道中读取任何的数据都必须首先读取到缓冲区里。
什么是缓冲区?
Buffer是一个对象,它包含一些要写入或者刚读出的数据。 在 NIO 中加入Buffer对象,体现了新库与原 I/O 的一个重要区别。在面向流的 I/O 中,您将数据直接写入或者将数据直接读到Stream对象中。在 NIO 库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的。在写入数据时,它是写入到缓冲区中的。任何时候访问 NIO 中的数据,您都是将它放到缓冲区中。缓冲区实质上是一个数组。通常它是一个字节数组,但是也可以使用其他种类的数组。但是一个缓冲区不仅仅是一个数组。缓冲区提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。
缓冲区类型
最常用的缓冲区类型是ByteBuffer。一个ByteBuffer可以在其底层字节数组上进行 get/set 操作(即字节的获取和设置)。ByteBuffer不是 NIO 中唯一的缓冲区类型。事实上,对于每一种基本 Java 类型都有一种缓冲区类型:
ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer
每一个Buffer类都是Buffer接口的一个实例。 除了ByteBuffer,每一个 Buffer 类都有完全一样的操作,只是它们所处理的数据类型不一样。因为大多数标准 I/O 操作都使用ByteBuffer,所以它具有所有共享的缓冲区操作以及一些特有的操作。
下面看一下FloatBuffer的简单例子:
1 import java.io.FileInputStream; 2 import java.io.FileNotFoundException; 3 import java.io.FileOutputStream; 4 import java.nio.ByteBuffer; 5 import java.nio.FloatBuffer; 6 import java.nio.channels.FileChannel; 7 8 // UseFloatBuffer 9 10 public class UseFloatBuffer { 11 12 public static void main(String[] args) throws Exception { 13 14 FloatBuffer fb=FloatBuffer.allocate(10); 15 for (int i=0; i<fb.capacity(); i++) { 16 float f=(float)((float)i/10*(2*Math.PI)); 17 fb.put(f); 18 } 19 fb.flip(); 20 while (fb.hasRemaining()){ 21 float f=fb.get(); 22 System.out.println(f); 23 } 24 } 25 }
什么是通道?
Channel是一个对象,可以通过它读取和写入数据。拿 NIO 与原来的 I/O 做个比较,通道就像是流。正如前面提到的,所有数据都通过 Buffer 对象来处理。您永远不会将字节直接写入通道中,相反,您是将数据写入包含一个或者多个字节的缓冲区。同样,您不会直接从通道中读取字节,而是将数据从通道读入缓冲区,再从缓冲区获取这个字节。简而言之,就是NIO的大致流程为:输入文件->缓冲区->通道->缓冲区->程序处理数据->缓冲区->通道->缓冲区->输出文件;I/O的大致流程为:输入文件->流->程序处理数据->流->输出文件。
通道类型
通道与流的不同之处在于通道是双向的。而流只是在一个方向上移动(一个流必须是InputStream或者OutputStream的子类),而通道可以用于读、写或者同时用于读写。
实践起来:NIO 中的读和写
读和写是 I/O 的基本过程。从一个通道中读取很简单:只需创建一个缓冲区,然后让通道将数据读到这个缓冲区中;写入也相当简单:创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作。
从文件中读取
如果使用原来的 I/O,那么我们只需创建一个FileInputStream并从它那里读取。而在 NIO 中,情况稍有不同:我们首先从FileInputStream获取一个Channel对象,然后使用这个通道来读取数据。
在 NIO 系统中,任何时候执行一个读操作,您都是从通道中读取,但是您不是直接从通道读取。因为所有数据最终都驻留在缓冲区中,所以您是通过通道读到缓冲区中的数据。
因此读取文件涉及三个步骤:
(1) 从FileInputStream获取Channel
(2) 创建Buffer
(3) 将数据从Channel读到Buffer中。
1 FileInputStream fin=new FileInputStream("read.txt"); 2 FileChannel fc=fin.getChannel(); 3 ByteBuffer buffer=ByteBuffer.allocate(1024); 4 fc.read(buffer);
写入文件
在 NIO 中写入文件类似于从文件中读取。首先从FileOutputStream获取一个通道;下一步是创建一个缓冲区并在其中放入一些数据 - 在这里,数据将从一个名为data的数组中取出,最后一步是写入缓冲区中。
1 FileOutputStream fout=new FileOutputStream("write.txt"); 2 FileChannel fc=fout.getChannel(); 3 ByteBuffer buffer=ByteBuffer.allocate(1024); 4 for (int i=0; i<data.length; i++) { 5 buffer.put(data[i]); 6 } 7 buffer.flip(); 8 fc.write(buffer);
实战练习
我们以一个名为 CopyFile.java 的简单程序作为这个练习的基础,它将一个文件的所有内容拷贝到另一个文件中。CopyFile.java 执行三个基本操作:首先创建一个Buffer,然后从源文件中将数据读到这个缓冲区中,然后将缓冲区写入目标文件。这个程序不断重复 ― 读、写、读、写 ― 直到源文件结束。
1 // CopyFile 2 3 import java.io.*; 4 import java.nio.*; 5 import java.nio.channels.*; 6 7 public class CopyFile { 8 9 static public void main( String args[] ) throws Exception { 10 String infile="E:\\北京欢迎你.txt"; 11 String outfile="E:\\out.txt"; 12 13 FileInputStream fin=new FileInputStream(infile); 14 FileOutputStream fout=new FileOutputStream(outfile); 15 FileChannel fcin = fin.getChannel(); 16 FileChannel fcout = fout.getChannel(); 17 18 ByteBuffer buffer = ByteBuffer.allocate(1024); 19 20 while (true) { 21 buffer.clear(); 22 int r=fcin.read(buffer); 23 if (r == -1) { 24 break; 25 } 26 buffer.flip(); 27 fcout.write(buffer); 28 } 29 } 30 }
转载于:https://www.cnblogs.com/BaiYiShaoNian/p/4916138.html
Java NIO入门相关推荐
- Java NIO 入门
在开始之前 关于本教程 新的输入/输出 (NIO) 库是在 JDK 1.4 中引入的.NIO 弥补了原来的 I/O 的不足,它在标准 Java 代码中提供了高速的.面向块的 I/O.通过定义包含数据的 ...
- java NIO入门小记
传统的IO模式 传统的IO流是阻塞式的,会一直监听一个ServerSocket,在调用read等方法时,他会一直等到数据到来或者缓冲区已满时才返回.调用accept也是一直阻塞到有客户端连接才会返回. ...
- JAVA NIO编程入门(二)
一.回顾 上一篇文章 JAVA NIO编程入门(一)我们学习了NIO编程的基础知识,并通过一个小demo实战帮助了解NIO编程的channel,buffer等概念.本文会继续学习JAVA NIO编程, ...
- Java NIO 非阻塞网络编程快速入门
NIO 非阻塞网络编程快速入门 案例: 编写一个 NIO 入门案例,实现服务器端和客户端之间的数据简单通讯(非阻塞) 目的:理解 NIO 非阻塞网络编程机制 import java.net.InetS ...
- Java基础入门(十八)之NIO
NIO的简介 1.java.nio 全称 java non-blocking IO 是jdk1.4之后出现的 New IO为所有的原始类型(boolean除外)提供了缓存支持 使用它 可以提供非阻塞式 ...
- java nio 海子_java 网络编程入门-NIO
这篇来讲解java网络编程之后高性能模型.NIO,有些书成为Non-blocking IO 非阻塞IO,这个是相对于BIO来说的.还有一种说法,New IO,顾名思义新的IO,这个是相对于旧版io的定 ...
- Java api 入门教程 之 JAVA的IO处理
IO是输入和输出的简称,在实际的使用时,输入和输出是有方向的.就像现实中两个人之间借钱一样,例如A借钱给B,相对于A来说是借出,而相对于B来说则是借入.所以在程序中提到输入和输出时,也需要区分清楚是相 ...
- java nio 断开连接_浅尝Java NIO与Tomcat连接调优
本文使用jdk1.8.0_45和spring boot 2.1.4.RELEASE 涉及源码都放在https://github.com/sabersword/Nio 前因 这周遇到一个连接断开的问题, ...
- Java NIO理解与使用
2019独角兽企业重金招聘Python工程师标准>>> Netty的使用或许我们看着官网user guide还是很容易入门的.因为Java nio使用非常的繁琐,netty对Java ...
- 你对Java网络编程了解的如何?Java NIO 网络编程 | Netty前期知识(二)
本文主要讲解NIO的简介.NIO和传统阻塞I/O有什么区别.NIO模型和传统I/O模型之间的对比.以及围绕NIO的三大组件来讲解,理论代码相结合. 很喜欢一句话:"沉下去,再浮上来" ...
最新文章
- mysql 自动管理内存_MySQL内存管理,内存分配器和操作系统
- 从产品经理向人工智能产品经理进阶 | 机器学习必备知识
- Linux中zip压缩和unzip解压缩
- java面向对象知识汇总的思维导图
- 乐峰VS聚美,明星也要吃咸盐
- Android 欢迎页面的编写
- markov chain, MRP MDP
- BugkuCTF-PWN题canary超详细讲解
- 注意儿童补钙有误区,汤臣倍健牛初乳加钙咀嚼片要用好
- 开源软件的中年危机如何破解?
- 【洛谷P1507 NASA的食物计划】动态规划
- Android版抢票神器使用指南及下载地址
- java mencoder_mencoder java linux
- 网页自动加拼音html,HTML5:给汉字加拼音?让我秀给你看
- pdn阻抗测试_非常详细的阻抗测试基础知识
- ckplayer播放器自动播放下一集以及点击下一集
- 详解GaussDB(DWS) 资源监控
- 手把手教你抄板(待更新)
- 2019_ACL_Multimodal Transformer for Unaligned Multimodal Language Sequences
- 第三周作业——广州视源电子科技有限公司面试感想
热门文章
- 神奇的机器人评课_神奇的机器人教学案
- kafka依赖_Kafka集群搭建及必知必会
- MyBatis-Plus 代码生成器报错
- 自定义注解和SpEL表达式实现功能强大的无侵入式的日志功能
- tomcat内存溢出解决方案_JVM了解以下?JVM系列~内存区域与内存溢出异常
- 5.3使用自定议的测试数据库文件
- [渝粤教育] 广东-国家-开放大学 21秋期末考试标准的研制与编制★10003k1
- virtual 关键字以及虚函数的介绍
- 如何在对话框程序中让对话框捕获WM_KEYDOWN消息
- 控制台——EventLog实现事件日志操作