IO与NIO
IO
IO概念:
Java IO
Java IO 即java的输入系统,不管我们编写任何种语言,都难免输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,还要考虑的因素特别多,比如我们要考虑哪种媒介进行IO(文件,控制台,网络),还要考虑具体的通信方式,(顺序,随机,二进制,按字,按行等等)。Java类库设计者设计大量的类来攻克,这些类就存在java.IO包中。
流
在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)。
Java IO类型
虽然java IO类库庞大,但总体来说,框架还是很清楚的,从是读媒介的维度来看,java IO还可以分为:
- 输入流:InputStream和Reader
- 输出流:OutputStream和Writer
处理的流类型维度来看,java IO 又可分为:
- 字节流:InputStream和OutputStream
- 字符流:Reader和Writer
Java IO的分类图:
Java IO:网络媒介
关于Java IO面向网络媒介的操作即Java 网络编程,其核心是Socket,同磁盘操作一样,java网络编程对应着两套API,即Java IO和Java NIO
Java IO:BufferedInputStream和BufferedOutputStream
BufferedInputStream顾名思义,就是在对流进行写入时提供一个buffer来提
高IO效率。在进行磁盘或网络IO时,原始的InputStream对数据读取的过程都
是一个字节一个字节操作的,而BufferedInputStream在其内部提供了一个,
buffer在读数据时,会一次读取一大块数据到buffer中,这样比单字节的操作效率
要高的多,特别是进程磁盘IO和对大量数据进行读写的时候。
Buffer:
//创建输入和输出流
Reader reader=null;
Writer writer=null;
BufferedReader br=null;
BufferedWriter bw=null;
try {
writer=new FileWriter("e:/a.txt",true);
bw=new BufferedWriter(writer); //封装
bw.write("大家辛苦了!");
bw.newLine(); //换行
bw.write("大家别眨眼!");
bw.flush();
bw.write("大家别眨眼22!");
bw.write("大家别眨眼33!");
bw.close();
writer.close(); //如果不关闭 后续两句话没法获取
//读取
reader=new FileReader("e:/a.txt");
br=new BufferedReader(reader);//封装
String line=null;
StringBuffer sb=new StringBuffer();
while ((line=br.readLine())!=null){
sb.append(line);
}
System.out.println(sb.toString());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
br.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
序列化与反序列化:
**
* 序列化和反序列化
* ObjectInputStream ObjectOutputStream
*/
public class ObjectDemo {
static Scanner input=new Scanner(System.in);
//创建需要的输入和输出流对象
static InputStream inputStream=null;
static OutputStream outputStream=null;
static ObjectInputStream objectInputStream=null;
static ObjectOutputStream objectOutputStream=null;
public static void main(String[] args) {
//注册 序列化
//register();
//登录 反序列化
login();
}
//注册
private static void register() {
User user=new User();
System.out.println("请输入您的用户名:");
user.setUserName(input.next());
System.out.println("请输入您的密码:");
user.setPassword(input.next());
try {
outputStream=new FileOutputStream("e:/user.txt");
objectOutputStream=new ObjectOutputStream(outputStream);
//把对象输出到文件中
objectOutputStream.writeObject(user);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
objectOutputStream.close();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//登录
private static void login() {
try {
inputStream=new FileInputStream("e:/user.txt");
objectInputStream=new ObjectInputStream(inputStream);
//读取对象
User user= (User) objectInputStream.readObject();
System.out.println(user);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
objectInputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
User类:
public class User implements Serializable{
private String userName;
private String password;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String userName, String password) {
this.userName = userName;
this.password = password;
}
public User() {
}
@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", password='" + password + '\'' +
'}';
}
NIO
Java io 回顾
Java 标准 IO 类库是 io 面向对象的一种抽象。基于本地方法的底层实现,我们无须关注底层实现。InputStream\OutputStream( 字节流 ) :一次传送一个字节。 Reader\Writer( 字符流 ) :一次一个字符。
nio 简介
nio 是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下:
为所有的原始类型提供 (Buffer) 缓存支持。
字符集编码解码解决方案。
Channel :一个新的原始 I/O 抽象。
支持锁和内存映射文件的文件访问接口。
提供多路 (non-bloking) 非阻塞式的高伸缩性网络 I/O 。
本文将围绕这几个特性进行学习和介绍。
Buffer&Chanel
Channel 和 buffer 是 NIO 是两个最基本的数据类型抽象。
Buffer:
是一块连续的内存块。
是 NIO 数据读或写的中转地。
Channel:
数据的源头或者数据的目的地
用于向 buffer 提供数据或者读取 buffer 数据 ,buffer 对象的唯一接口。
异步 I/O 支持
channel和buffer关系图:
NIO的新特性
总的来说java 中的IO 和NIO的区别主要有3点:
IO是面向流的,NIO是面向缓冲的;
IO是阻塞的,NIO是非阻塞的;
IO是单线程的,NIO 是通过选择器来模拟多线程的;
NIO在基础的IO流上发展处新的特点,分别是:内存映射技术,字符及编码,非阻塞I/O和文件锁定。下面我们分别就这些技术做一些说明。
内存映射
这个功能主要是为了提高大文件的读写速度而设计的。内存映射文件(memory-mappedfile)能让你创建和修改那些大到无法读入内存的文件。有了内存映射文件,你就可以认为文件已经全部读进了内存,然后把它当成一个非常大的数组来访问了。将文件的一段区域映射到内存中,比传统的文件处理速度要快很多。内存映射文件它虽然最终也是要从磁盘读取数据,但是它并不需要将数据读取到OS内核缓冲区,而是直接将进程的用户私有地址空间中的一部分区域与文件对象建立起映射关系,就好像直接从内存中读、写文件一样,速度当然快了。
NIO中内存映射主要用到以下两个类:
1.java.nio.MappedByteBuffer
2.java.nio.channels.FileChannel
NIO增加新功能
- 有选择器
选择器(Selectors)
Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
- 可以只用正则表达式
- 支持内存映射
- 支持文件锁
Buffer 缓冲区
本质是一个写入数据,并且从中读取数据的内存!
存储的是相同数据类型的值
1.position:写入或读取的是数据的当前指针,最大值:capacity-1
2.Limit:有多少数据可以写或者可以读
在write模式下,我们limit和capacity的值一致
再read模式下limit和write模式下的position的值一致
在read模式下代表的就是最大的读取量(写多少读多少)
3.Capacity:缓冲区的最大容量
Buffer
传统的I/O不断的浪费对象资源(通常是String)。新I/O通过使用Buffer读写数据避免了资源浪费。Buffer对象是线性的,有序的数据集合,它根据其类别只包含唯一的数据类型。
java.nio.Buffer 类描述
java.nio.ByteBuffer 包含字节类型。 可以从ReadableByteChannel中读在 WritableByteChannel中写
java.nio.MappedByteBuffer 包含字节类型,直接在内存某一区域映射
java.nio.CharBuffer 包含字符类型,不能写入通道
java.nio.DoubleBuffer 包含double类型,不能写入通道
java.nio.FloatBuffer 包含float类型
java.nio.IntBuffer 包含int类型
java.nio.LongBuffer 包含long类型
java.nio.ShortBuffer 包含short类型
可以通过调用allocate(int capacity)方法或者allocateDirect(int capacity)方法分配一个Buffer。特别的,你可以创建MappedBytesBuffer通过调用FileChannel.map(int mode,long position,int size)。直接(direct)buffer在内存中分配一段连续的块并使用本地访问方法读写数据。非直接(nondirect)buffer通过使用Java中的数组访问代码读写数据。有时候必须使用非直接缓冲例如使用任何的wrap方法(如ByteBuffer.wrap(byte[]))在Java数组基础上创建buffer。
字符编码
向ByteBuffer中存放数据涉及到两个问题:字节的顺序和字符转换。ByteBuffer内部通过ByteOrder类处理了字节顺序问题,但是并没有处理字符转换。事实上,ByteBuffer没有提供方法读写String。
Java.nio.charset.Charset处理了字符转换问题。它通过构造CharsetEncoder和CharsetDecoder将字符序列转换成字节和逆转换。
通道(Channel)
你可能注意到现有的java.io类中没有一个能够读写Buffer类型,所以NIO中提供了Channel类来读写Buffer。通道可以认为是一种连接,可以是到特定设备,程序或者是网络的连接
IO与NIO的更多相关文章
- java的nio之:java的nio系列教程之java的io和nio的区别
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- 面试题_66_to_75_Java IO 和 NIO 的面试题
IO 是 Java 面试中一个非常重要的点.你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识.下面是 Java IO 中经常问的问题. 66)在我 Java ...
- 传统IO与NIO的比较
本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...
- Java IO 和 NIO
昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...
- JAVA中IO和NIO的详解分析,内容来自网络和自己总结
用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...
- Nio学习4——EchoServer在IO,NIO,NIO.2中的实现
堵塞IO实现: public class PlainEchoServer { public void serve(int port) throws IOException { final Server ...
- 理解IO、NIO、 AIO
转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...
- Java NIO:IO与NIO的区别
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
- 【杂谈】对IO与NIO的认识
IO流与NIO块的数据缓存 Java的IO是面向流设计的,通常我们通过IO流读取数据,只能指定读取数据的大小,而不能选择数据读取的起始位置.数据就像流水一样,流过我们的应用,一旦流过就无法回头.除非我 ...
- Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?
IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...
随机推荐
- oracle入门(6)——PL/SQL常用语法
[本文介绍] 本文不是”语法大全“,只是记录下作项目里自己常用的一些语法.方便查询. [语法] [输出] (1)输出语法 DBMS_OUTPUT.PUT_LINE( ) [定义] (1)定义变 ...
- java-mybaits-00501-案例-映射分析-订单商品数据模型
1.数据模型分析思路 1.每张表记录的数据内容 分模块对每张表记录的内容进行熟悉,相当 于你学习系统 需求(功能)的过程. 2.每张表重要的字段设置 非空字段.外键 ...
- 如何保护自己的GitHub代码不被别人覆盖
我们在自己的github上创建了免费的公开代码,为了防止别人通过git push upstream master 覆盖了自己原有的代码,需要作一下设置:Settings->Branchs,然后在 ...
- 模块讲解----sys
sys:跟python解释器相关的信息 #命令行参数list,第一个元素时程序本身路径 print(sys.argv) 注意:执行脚本时,可以传参数. #退出程序,正常退出时exit(0) sys.e ...
- 记录:正确率、召回率、F值
因为不理解召回率,所以去查看了一些资料.特此记录一下自己的理解,以便以后查看. 说明 正确率=查出来正确的样本数/全部查出来的样本数 (也可以理解为查准率) 召回率=查出来正确的样本数/数据集里全部正 ...
- 关于safenetde 的明文 密文 数据 。这个数组使用 safenet的助手 产生的。
关于safenetde 的明文 密文 数据 .这个数组使用 safenet的助手 产生的. 下图是生成的数组 例如: { 0x9B, 0xFD, 0xF5, 0xA6, 0xF5, 0x57, 0 ...
- python全栈开发从入门到放弃之迭代器生成器
1.python中的for循环 l = [1,2,3,4,5,6] for i in l: #根据索引取值 print(i) 输出结果: 1 2 3 4 5 6 2.iterable 可迭代的 可迭 ...
- python全栈开发从入门到放弃之初识面向对象
面向过程 VS 面向对象 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程序的复 ...
- C# 使用 SqlBulkCopy 类批量复制数据到数据库
最近公司需要优化导入的问题,由于之前使用的方式是生成 Insert 语句插入数据库,数据量小的时候还行,但是随着发展数据量渐渐大了,之前的方法性能就跟不上了,于是发现了 SqlBulkCopy 这个类 ...
- PKU 2559 Largest Rectangle in a Histogram(单调栈)
题目大意:原题链接 一排紧密相连的矩形,求能构成的最大矩形面积. 为了防止栈为空,所以提前加入元素(-1,0) #include<cstdio> #include<stack> ...