IO

IO概念:

Java IO

Java IO 即java的输入系统,不管我们编写任何种语言,都难免输入输出相关的媒介打交道,其实和媒介进行IO的过程是十分复杂的,还要考虑的因素特别多,比如我们要考虑哪种媒介进行IO(文件,控制台,网络),还要考虑具体的通信方式,(顺序,随机,二进制,按字,按行等等)。Java类库设计者设计大量的类来攻克,这些类就存在java.IO包中。

在Java IO中,流是一个核心的概念。流从概念上来说是一个连续的数据流。你既可以从流中读取数据,也可以往流中写数据。流与数据源或者数据流向的媒介相关联。在Java IO中流既可以是字节流(以字节为单位进行读写),也可以是字符流(以字符为单位进行读写)。

Java IO类型

虽然java IO类库庞大,但总体来说,框架还是很清楚的,从是读媒介的维度来看,java IO还可以分为:

  1. 输入流:InputStream和Reader
  2. 输出流:OutputStream和Writer

处理的流类型维度来看,java IO 又可分为:

  1. 字节流:InputStream和OutputStream
  2. 字符流: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增加新功能

  1. 有选择器

选择器(Selectors)

Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

  1. 可以只用正则表达式
  2. 支持内存映射
  3. 支持文件锁

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的更多相关文章

  1. java的nio之:java的nio系列教程之java的io和nio的区别

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

  2. 面试题_66_to_75_Java IO 和 NIO 的面试题

    IO 是 Java 面试中一个非常重要的点.你应该很好掌握 Java IO,NIO,NIO2 以及与操作系统,磁盘 IO 相关的基础知识.下面是 Java IO 中经常问的问题. 66)在我 Java ...

  3. 传统IO与NIO的比较

    本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...

  4. Java IO 和 NIO

    昨天面试问到了有关Java NIO的问题,没有答上来.于是,在网上看到了一篇很有用的系列文章讲Java IO的,浅显易懂.后面的备注里有该系列文章的链接.内容不算很长,需要两个小时肯定看完了,将该系列 ...

  5. JAVA中IO和NIO的详解分析,内容来自网络和自己总结

    用一个例子来阐释: 一辆客车上有10个乘客,他们的目的地各不相同,当没有售票员的时候,司机就需要不断的询问每一站是否有乘客需要下车,需要则停下,不需要则继续开车,这种就是阻塞的方式. 当有售票员的时候 ...

  6. Nio学习4——EchoServer在IO,NIO,NIO.2中的实现

    堵塞IO实现: public class PlainEchoServer { public void serve(int port) throws IOException { final Server ...

  7. 理解IO、NIO、 AIO

    转载:https://baijiahao.baidu.com/s?id=1586112410163034993&wfr=spider&for=pc nio 同步: 自己亲自出马持银行卡 ...

  8. Java NIO:IO与NIO的区别

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

  9. 【杂谈】对IO与NIO的认识

    IO流与NIO块的数据缓存 Java的IO是面向流设计的,通常我们通过IO流读取数据,只能指定读取数据的大小,而不能选择数据读取的起始位置.数据就像流水一样,流过我们的应用,一旦流过就无法回头.除非我 ...

  10. Java提供了哪些IO方式?IO, BIO, NIO, AIO是什么?

    IO一直是软件开发中的核心部分之一,而随着互联网技术的提高,IO的重要性也越来越重.纵观开发界,能够巧妙运用IO,不但对于公司,而且对于开发人员都非常的重要.Java的IO机制也是一直在不断的完善,以 ...

随机推荐

  1. Theme Section---hdu4763(kmp, Next数组的运用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4763 题意就是求s串中满足EAEBE格式的E的最大长度:我们可以枚举前缀和后缀的所有匹配(k)看是否在 ...

  2. 理解Global interpreter lock

      Global interpreter lock (GIL) is a mechanism used in computer language interpreters to synchronize ...

  3. IIS 搭建过程

      Windows自带iis管理器,也就是这个 <ignore_js_op> 我们可以用它来搭建一个网站,然后在局域网内可随意访问我们的电脑.   1.首先,iis的安装.        ...

  4. js中将Object转换为String函数代码

    经常会碰到结果对象是object而无法查看该对象里面的内容而苦恼,有下面这个函数就好了,可以将其转化为字符串类型,然后就可以打印出来了,具体代码如下: function obj2string(o){ ...

  5. TWebBrowser: Determine when a page with Frames is completed

    TWebBrowser: Determine when a page with Frames is completed 6 comments. Current rating: (3 votes). L ...

  6. Linux系统——awk命令

    awk命令不仅仅是Linux系统的命令,也是一种编程语言,用来处理数据和生成报告(Exel),处理的数据可以是一个或多个文件(标准输入和管道获取标准输入).可在命令行上编辑操作,也可以写成awk程序运 ...

  7. C#:对含有中文的字符串进行MD5加密

    MD5CryptoServiceProvider MD5 = new MD5CryptoServiceProvider(); var Sign = BitConverter.ToString(MD5. ...

  8. log4j相关配置

    1.概述         log4j是Apache提供的一个日志实现,可以用于我们项目中的日志记录,有log4j1和log4j2两个版本,本文使用log4j2这个版本.SLF4J(Simple log ...

  9. hdu6121 Build a tree

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6121 题面: Build a tree Time Limit: 2000/1000 MS (J ...

  10. QUIC协议

    QUIC协议 QUIC协议参考网址 https://www.chromium.org/quic 既生瑜,何生亮? QUIC的特性 提供可靠传输 减少连接建立的时间 改善拥塞控制 多路复用 转发错误连接 ...