JavaNIO(一)(IO基本概念扫盲篇)

一、基本IO概念



1、什么是流IO?

    1.1 基本概念

   流是一种抽象概念,它代表了数据的无 结构化传递。 按照流的方式进行输入输出,数据被当成无结构的字节序或字符序列。从流中取得数据的操作称为提取操作,而 向流中添加数据的操作称为插入操作。用来进行输入输出操作的流就称为IO流。换句话说,IO流就是以流的方式进行输入输出。输入输出(IO)是指计算机同 任何外部设备之间的数据传递。常见的输入输出设备有文件、键盘、打印机、屏幕等。数据可以按记录(或称数据块)的方式传递,也可以流的方式传递。

1.2 形象比喻

  流(stream)的概念源于UNIX中管道(pipe)的概念。在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备、外部文件等。一 个流,必有源端和目的端,它们可以是计算机内存的某些区域,也可以是磁盘文件,甚至可以是Internet上的某个URL。流的方向是重要的,根据流的方 向,流可分为两类:输入流和输出流。用户可以从输入流中读取信息,但不能写它。相反,对输出流,只能往输入流写,而不能读它。
       实际上,流的源端和目的端可简单地看成是字节的生产者和消费者,对输入流,可不必关心它的源端是什么,只要简单地从流中读数据,而对输出流,也可不知道它的目的端,只是简单地往流中写数据。形象的比喻——水流 ,文件======程序 ,文件和程序之间连接一个管道,水流就在之间形成了,自然也就出现了方向:可以流进,也可以流出。便于理解,这么定义流: 流就是一个管道里面有流水,这个管道连接了文件和程序。

2. 字节流和字符流的区别

   字节流与字符流主要的区别是他们的的处理方式。

   字节流是最基本的,所有的InputStream和OutputStream的子类都是,主要用在处理二进制数据,它是按字节来处理的。但实际中很多的数据是文本,又提出了字符流的概念,它是按虚拟机的encode来处理,也就是要进行字符集的转化这两个之间通过 InputStreamReader,OutputStreamWriter()来关联,实际上是通过byte[]和String来关联。在实际开发中出现的汉字问题实际上都是在字符流和字节流之间转化不统一而造成的。

1 public String(byte bytes[], String charsetName)

    在从字节流转化为字符流时,实际上就是byte[]转化为String时,有一个关键的参数字符集编码,通常我们都省略了,那系统就用操作系统的 lang。而在字符流转化为字节流时,实际上是String转化为byte[]时,byte[] String.getBytes(String charsetName),也是一样的道理。至于java.io中还出现了许多其他的流,按主要是为了提高性能和使用方便,如 BufferedInputStream,PipedInputStream等。

注:InputStreamReader源码

//是字节流转换成字符流,按照某种编码的方式
public InputStreamReader(InputStream in) {
        super(in);
        try {
//这里的StreamDecoder源码看不到
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

    个人理解:

    1、单就IO流来讲,“流”传输的东西始终是无结构的一个个字节序列,字节流和字符流的区别在于,它们是基于不同的“协议”处理这些字节:

    2、字节流----按照面向字节处理数据,支持8位结构的字节,不能很好的处理16位Unicode字符。只能用于处理图像、音频等文件;

      字符流----按照面向字符处理数据,能够较好的处理16位的Unicode字符(比如char类型),更好的处理字符类型。(提高效率)

    3、处理数据源的时候,尽量使用字符流。另外IO流中大量使用的装饰器模式:这也是处理单一流对象,却要创建这么多对象。提高工作效率。

2、什么是块IO?

    2.1 基本概念

  所谓记录,是指有着内部结构的数据块。记录内部除了有需要处理的实际数据之外,还可能包含附加信息,这些附加信息通常是对本记录数据的描述。

3、Java流IO和块IO有什么区别?

   操作系统并非不能快速传送数据,让 Java 有事可做;相反,是 JVM 自身在 I/O 方面效率欠佳。 操作系统与 Java 基于流的 I/O模型有些不匹配。 操作系统要移动的是大块数据(缓冲区),这往往是在硬件直接存储器存取(DMA)的协助下完成的。而 JVM 的 I/O 类喜欢操作小块数据——单个字节、几行文本。结果,操作系统送来整缓冲区的数据,java.io 的流数据类再花大量时间把它们拆成小块,往往拷贝一个小块就要往返于几层对象。操作系统喜欢整卡车地运来数据,java.io 类则喜欢一铲子一铲子地加工数据。有了 NIO,就可以轻松地把一卡车数据备份到您能直接使用的地方(ByteBuffer 对象)。 
  1)面向流I/O的系统:
次处理一个字节的数据。一个输入流每次会读入一个字节的数据,一个输出流同样每次次消费一个字节的数据。对于流式数据,很容易创建过滤器。可以相对简单地
把几个过滤器连接在一起,每个过滤器完成自己的工作,也是按字节进行过滤,精细的处理机制。另一方面,面向流I/O的通信往往比较缓慢。 
  2)面向块I/O的系统:以块为单位处理数据。每个操作步骤会生成或消费一个块的数据。以块为单位处理数据,其处理速度远快于以字节流为单位的方式。但是,与面向流I/O的通信相比,面向块I/O的通信缺乏优雅和简洁。 但是有更高的数据吞吐量(指对网络、设备、端口、虚电路或其他设施,单位时间内成功地传送数据的数量)。

  个人理解:

  NIO:NIO模型,不再使用原来的IO模型(往流中读写数据),而是要从缓存区往通道读写数据。那有人又要问,我IO流对象经过BufferInputStream包装一下,不也可以按“缓存区”读吗?

  但是,NIO缓冲区的底层实现将缓冲区ByteBuffer直接与硬件或者内存连接;而IO是操作系统内存将数据复制到JVM内存中,再在JVM内存上进行操作。

4、流和通道的区别:从编程角度来讲,流是基于字节的,而通道是基于块的。

    1、从基本概念上看,流设计为一次传送一个字节的数据。而通道会传送缓冲区中的数据块。可以读写通道的字节之前,这些字节必须存在缓存区中,而且一次性会读写一个缓存区的数据。

    2、通道和缓冲区支持对同一个对象的读写,程序可以读写同一个通道;而流,分为读/写两种。

    3、除了数据列表以外,每个缓冲区还记录了信息的4个关键部分:

        位置(pos) 缓冲区中将读取或写入的下一个位置。

        容量(cap) 缓冲区可以保存的元素的最大数目。

        限度(lim)  缓存区可以访问数据的末尾位置。

        标记(mark)缓冲区客户端指引的索引。

    4、与读取InputStream不同,读取缓冲区实际上不会以任何方式改变缓冲区中的数据。只可能向前或向后设置位置,从而可以从缓冲区中某个特定位置开始读取(灵活)。而IO流只能从某个位置开始一个个去读写(固定)。Buffer在实现上本质是一个数组,其作用是一个存储器,或者分段运输区,并且提供了对数据的结构化访问,而且还可以跟踪系统的读/写进程。

二、同步/异步  阻塞/非阻塞



(透彻版:http://www.zhihu.com/question/19732473)

(详细版:http://www.cnblogs.com/zhuYears/archive/2012/09/28/2690194.html)

看完这两篇博文的个人理解:

1、同步与异步(消息通知机制):

同步:线程去调用资源的时候,如果资源没有准备好,那么线程会一直等待,当资源准备好了,那么该线程就调用该资源,并返回资源;

异步:线程只负责发出一个调用通知,不管资源准没准备好,我都立刻返回。等资源准备好,会自己借助别的方式返回。(在Linux中会使用内核返回、回调)

2、阻塞与非阻塞:该线程的等待调用结果的状态:

阻塞:如果去调某个资源的时候,没有准备好,那么线程被挂起,等到资源准备好,返回可以调用的标识,线程再被“启用”。

非阻塞:如果去调某个资源的时候,如果该资源已经准备好,那么线程就可以直接调取该资源;如果资源没有准备好,那么该线程就处理别的事情,时不时过来看看资源有没有准备好(资源返回的标志位)

ps:把自己平时容易混淆的东西记录下来,想到什么就加上了,所以有些乱。。。后面会正式步入JavaNIO

参考博客:

http://www.cnblogs.com/pepcod/archive/2013/01/20/2913435.html

百度百科

http://my.oschina.net/OutOfMemory/blog/95853

《Java网络编程 第四版》

时间: 2024-10-07 06:00:34

JavaNIO(一)(IO基本概念扫盲篇)的相关文章

工作流学习——重要概念扫盲篇一步曲

前言 从本篇文章我们开始介绍工作流框架activiti的相关知识,不过在介绍activiti的知识之前,我们很有必要对工作流的一些基本概念进行了解. 工作流重要概念 Workflow Workflow(工作流)是"业务过程的部分或整体在计算机应用环境下的自动化,是对工作流程及其各操作步骤之间业务规则的抽象.概括描述",它主要解决的是"使在多个参与者之间按照一种提前定义好的规则流程来传递与执行文档.信息或任务的过程,让这个过程可以自动进行或者部分自动执行,从而完成预期的业务目标

iOS网络缓存扫盲篇--使用两行代码就能完成80%的缓存需求

iOS网络缓存扫盲篇 --使用两行代码就能完成80%的缓存需求 下篇预告:使用80%的代码来完成剩下的20%的缓存需求 .敬请 star (右上角)持续关注. 目录 当我们在谈论缓存的时候,我们在谈论什么? GET网络请求缓存 80%的缓存需求:两行代码就可满足 控制缓存的有效性 文件缓存:借助ETag或Last-Modified判断文件缓存是否有效 Last-Modified ETag 总结 一般数据类型借助 Last-Modified 与 ETag 进行缓存 剩下20%的网络缓存需求--真的

java学习之入门扫盲篇

概要 最近这几天开始进入java的学习,接触到了好多不是很了解的概念,像JDK.JRE.JVM.GC等等这些,放到这里来进行下扫盲. java java是一种面向对象程序设计语言和java平台的总称,即java包括java语言和java平台. java语言 java语言跟我们以前接触过的C#.C++语言一样都是面向对象的语言,拥有面向对象语言的基本特点,java语言也有它自身的特点,例如增加了垃圾回收的一些特点.同时java语言的编程风格跟C#.C++也特别的相似,所有java语言是比较易学的.

Docker基础--概念扫盲

学习使用Docker之前,有必要做一下功课,对相应的概念有一个基本.清晰的了解,这样也有助于帮助自己更好的使用.这篇文章主要介绍以下知识: 什么是容器? Docker是什么? Docker与传统虚拟机对比 Docker基本概念扫盲:镜像(Image).容器(Container).仓库(Repository) 1.什么是容器? 容器从字面意思理解就是装东西.软件中容器技术一词来源于Linux Container英文单词的直译. container n. 容器; 集装箱; 货柜 2.什么是Docke

win7扫盲篇--介绍安装(1)

1.硬件+操作系统+软件应用=用户电脑 2.win7  2007年 winXP 2001年  不能兼容64位 win98 1998年 UNIX  银行操作系统 Linux开源自由的操作系统,安全稳定比较出色,在服务领域使用广泛,安卓是基于Linux操作系统 Mac OS苹果操作系统 MS-DOS 命令行操作 3.win7版本 win7家庭普通版的功能最少,简装版本 win7旗舰版,功能最多 硬件需求 cpu1GH以上,内存1G以上,硬盘16G以上,32位最多支持3个G得内存 cpu1GH以上,内

敏捷开发之Scrum扫盲篇

敏捷开发之Scrum扫盲篇 现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中的各个环节,主要目的有两个,一个是进行知识的总结,另外一个是觉得网上很多学习资料的讲述方式让初学者不太容易理解:所以我决定写一篇扫盲性的博文,同时试着也与园内的朋友一起分享交流一下,希望对初学者有帮助.  什么是敏捷开发? 敏捷开发(Agile Development)是

第8章双路由双网段网络互通实验(扫盲篇)

第8章双路由双网段网络互通实验(扫盲篇) 一  实验目的 学习如何给路由器接口配置IP.子网掩码 学习如何给路由器配置静态路由 学习如何在GNS3软件下给电脑主机配置IP 二  实验工具 GNS3软件   http://yunpan.cn/cwkDa4MWJwiiV  访问密码 9b1a 思科IOS    http://yunpan.cn/cjDjwg4CXMxpw  访问密码 9c14 三  实验步骤 如图所示在GNS3的模拟环境下,两台路由R1和R2,下面各接1台电脑,要求这2台电脑在不同网

01--Qt扫盲篇

Qt扫盲篇 1.What is Qt 一个跨平台应用程序和UI开发框架,主要偏向于UI框架方面,由诺基亚公司开发维护. 使用 Qt 只需一次性开发应用程序,无须重新编写源代码,便可跨不同桌面和嵌入式操作系统部署这些应用程序,Qt 支持以下平台: 直观的 C++跨平台类库(封装,SDK) 跨桌面和嵌入式操作系统的移植性(跨平台) 具有跨平台 IDE 的集成开发工具(Qt Creator) 在嵌入式系统上的高运行时间性能,占用资源少(手机MeeGo,N9) 2.Use Qt 下载Qt SDK(htt

iOS开发笔记--敏捷开发之Scrum扫盲篇

敏捷开发之Scrum扫盲篇 现在敏捷开发是越来越火了,人人都在谈敏捷,人人都在学习Scrum和XP... 为了不落后他人,于是我也开始学习Scrum,今天主要是对我最近阅读的相关资料,根据自己的理解,用自己的话来讲述Scrum中的各个环节,主要 目的有两个,一个是进行知识的总结,另外一个是觉得网上很多学习资料的讲述方式让初学者不太容易理解:所以我决定写一篇扫盲性的博文,同时试着也与园内的 朋友一起分享交流一下,希望对初学者有帮助.  什么是敏捷开发? 敏捷开发(Agile Development