Javaor .net编程中,  我们经常见到"stream" 这个字眼.

我们大概知道这是个流的意思, 如果看完本文的话, 应该会有1个大概的概念.

一, Java中什么是Stream(流)

1.1 1段输出文件内容到屏幕的代码

假如我们有个需求, 利用Java写1个程序, 将1个硬盘上的文件(/home/gateman/tmp/build.xml)内容输出到屏幕上.

Java的代码如下:

  1. import java.io.*;
  2. public class Stream1{
  3. public static void f() throws IOException{
  4. FileReader fr = new FileReader("/home/gateman/tmp/build.xml");
  5. int ch; //not char
  6. ch = fr.read(); //throws IOEXCEPTION
  7. while(ch > -1){ //if ch = -1, means got the end of the file
  8. System.out.printf("%c",(char)ch);
  9. ch = fr.read(); //throws IOEXCEPTION
  10. }
  11. }
  12. }

上面的代码很简单,

1.首先我们见到代码定义了1个 FileReader 对象fr.  它的某个成员指向了我们要读的文件build.xml.

2.然后多次执行 fr.read()方法, 每执行一次, 将fr.read()打返回结果输出到屏幕. 直到fr.read()的返回值是-1.

这里包括我也许有人会想, 为什么要 read 那么多次啊, 干脆写1个强大的read()方法把文件内容都读过来不就完了吗?

这就是涉及了流的概念.

1.2 搬水的例子

我们来举个例子让大家更加容易理解

问题1:

假如有两个杯子, 其中1个有水, 另1个没有水,  它们的位置都不能移动.

请问有什么方法将有水杯子了的水搬去另1个杯子?

答案很多种,  只需要1个碗, 把水倒进碗里, 然后把碗的水倒进另1个杯子里就ok了.

将这个思路应用到1.1 的例子, 就相当于1个强大的Read()方法把整个文件都读完了.

为什么这样说?

1. 我们可以把有水的杯子看做1个文件, 水相当于文件的内容.

2. 没水的杯子相当于屏幕. 我们就是需要把文件的内容输出到屏幕

3. 中间的碗相当于内存,  把有水的杯子的水倒进碗就是一次过把文件所有内容读入内存啊.

4. 最后把碗的水倒进另1个杯子, 相当于把内存里的内容输出到屏幕.

如下图:

问题貌似解决了, 但是随着这个问题的规模的扩大, 这个方法就不可行了.

例如需要搬运的不是一杯水,   而是把整个个池塘的水运到另一个池塘.

用碗来搬就不符合实际啊.

有人回说, 我一碗一晚的搬总会搬完?

问题是, 那个碗(内存)还可以其他东西,  如果整个内存都用于搬运数据, 那么就导致程序在搬运数据的时间里占用大部分操作系统的内存.  留给其他程序的内存就很少了!

1.3 搬水的例子的另1个解决方法: 管道

假如我们的内存(碗)容量很少, 但是要搬运整个池塘怎么办呢?

其实我们就可以用一条水管接通两个池塘.

管道上有1个按钮, 每按1次那个按钮, 就允许一点水通过管道.

如下图:

结合1.1 的java代码例子

实际上我们已经明白,  FileReader fr 这个对象就相当于1条管道, 这个管道有1个按钮 fr.read(), 每执行1次, 就有一点水流(1个字符) 读到内存(注意是内存, 而不是屏幕)!

1.4 本文开始1.1节java代码的分析

我们再看回1.1 的代码.

  1. FileReader fr = new FileReader("/home/gateman/tmp/build.xml");

当执行碗上面的代码后,

实际上建立了1条 从文件到内存的一条数据管道.

但是这时只是搭建好了1个管道, 并没有数据传输

  1. ch = fr.read(); //throws IOEXCEPTION

当执行1次 fr.read() 时,  就从文件读取一个字符, 并把这个字符保存入内存(Stack内存 ch变量)中.

这个方法需要处理IOException

  1. while(ch > -1){ //if ch = -1, means got the end of the file
  2. System.out.printf("%c",(char)ch);
  3. ch = fr.read(); //throws IOEXCEPTION
  4. }

这个也不难理解, 每读到1个字符, 就把这个字符输出到屏幕上, 直到读完整个文件.

如下图:

而第一句建立的对象 FileReader fr实际上就是1个文件读字符流

流(Stream)实际上就是从数据文件到程序的一条管道.

至于数据怎么从程序输出到屏幕, 这个并不是流的范畴.

1.5 Java Stream流的定义

看完上面例子的话, 流的定义就很容易看懂了.

Stream是java的1个类, 这个类专门用于程序和外部设备的输入输出(IO). 基本上所有流都在 java.io这个包中.

实际上Stream就是数据在程序和外部设备的单向管道, 流的各种方法相当于管道上的各种按钮.

所谓的外部设备可以包括硬盘文件, 网络设备, 另个程序等. 也就是当前程序之外的数据设备.

二, 为什么需要Stream(流).

看懂了上面的的例子, Stream存在的意义也很简单.

1. 数据的传输量很大.

2. 内存有限.

3. 带宽有限.

而Stream可以1点1点地逐步传输所有数据, 这就是Stream存在的根本意义.

想想我们是怎样下载1个大文件的, 下载软件(例如x雷)并不会占用你内存很大的空间, 而只是在内存划分1个缓冲区, 一点一点地下载到自己的内存(缓冲区满了再写到硬盘), 这也是流的1个例子啊.

三,流的重要特性.

3.1 流是java里的一个类

也就是将流就是类的一种, 但反过来类不是流

3.2 数据并不会在流里自动传输

而是需要执行流的方法, 一次传输一定量的数据.

3.3 1个流对象只有1个传输方向

也就是说流是单向的, 数据要么从程序到设备(OutputStream), 要么从设备到程序(InputStream).

http://blog.csdn.net/nvd11/article/details/29917065

Java Stream简介, 流的基本概念的更多相关文章

  1. 了解PHP中Stream(流)的概念与用法(转)

    Stream是PHP开发里最容易被忽视的函数系列(SPL系列,Stream系列,pack函数,封装协议)之一,但其是个很有用也很重要的函数.Stream可以翻译为“流”,在Java里,流是一个很重要的 ...

  2. 了解PHP中Stream(流)的概念与用法

    Stream是PHP开发里最容易被忽视的函数系列(SPL系列,Stream系列,pack函数,封装协议)之一,但其是个很有用也很重要的函数.Stream可以翻译为“流”,在Java里,流是一个很重要的 ...

  3. Java Stream函数式编程第三篇:管道流结果处理

    一.Java Stream管道数据处理操作 在本号之前写过的文章中,曾经给大家介绍过 Java Stream管道流是用于简化集合类元素处理的java API.在使用的过程中分为三个阶段.在开始本文之前 ...

  4. [源码解析] 当 Java Stream 遇见 Flink

    [源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...

  5. Java修炼——IO流的概念以及其分类

    IO流的基本概念: 流的原理: 1) 在 Java 程序中,对于数据的输入/输出操作以"流" (stream) 方式进行: 2) J2SDK 提供了各种各样的"流&quo ...

  6. 深度掌握 Java Stream 流操作,让你的代码高出一个逼格!

    概念 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选.排序.聚合等. Stream 的操作符大体上分为两种:中间操作符和终止操作符 中 ...

  7. 【转】输入/输出流 - 深入理解Java中的流 (Stream)

    基于流的数据读写,太抽象了,什么叫基于流,什么是流?Hadoop是Java语言写的,所以想理解好Hadoop的Streaming Data Access,还得从Java流机制入手.流机制也是JAVA及 ...

  8. Java IO 理解流的概念

    Java IO 理解流的概念 @author ixenos 在理解流时首先理解以下概念 1.流的来源和去向一般在构造器指出 2.方法中的形参一般是将流输出到某个位置,读取(INPUT)流从流读出数据( ...

  9. java 并发多线程显式锁概念简介 什么是显式锁 多线程下篇(一)

    目前对于同步,仅仅介绍了一个关键字synchronized,可以用于保证线程同步的原子性.可见性.有序性 对于synchronized关键字,对于静态方法默认是以该类的class对象作为锁,对于实例方 ...

随机推荐

  1. SpringBoot ( 八 ) :RabbitMQ 详解

    原文出处: 纯洁的微笑 RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息中间件在互联网公司的使用中越来越多,刚才还看到新闻阿里将Roc ...

  2. OpenCV---Numpy数组的使用以及创建图片

    一:对头像的所有像素进行访问,并UI图像进行像素取反 (一)for循环取反 import cv2 as cv import numpy as np def access_pixels(image): ...

  3. gulpfile.js文档

    gulp watch 实现监听不仅需要package.json文档,还需要gulpfile.js文档.否则无法实现. 1.gulp的安装 1.1 首先必须先安装node.js.这个可以参考之前的博客& ...

  4. 贪心+离散化+线段树上二分。。。 Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest G. Of Zorcs and Axes

    题目链接:http://codeforces.com/gym/101149/problem/G 题目大意:给你n对数字,为(a[i], b[i]),给你m对数字,为(w[i], c[i]).给n对数字 ...

  5. 超越icon font

    很久以前,我们如何使用图标? 1.切图 2.拼合(Sprites) 原始社会啊! 后来CSSGagagrunt-css-sprite 字体图标 相见不曾相识 Emoji绘文字 iconfont.cn直 ...

  6. 关于aspx.designer.cs的研究

    .aspx文件..aspx.cs文件和.aspx.designer.cs的一些说明 .aspx文件:(页面)书写页面代码.存储的是页面design代码.只是放各个控件的代码,处理代码一般放在.cs文件 ...

  7. JS设计模式——3.封装与信息隐藏

    封装.信息隐藏与接口的关系 信息隐藏是目的,封装是手段. 接口提供了一份记载着可供公共访问的方法的契约.它定义了两个对象间可以具有的关系.只要接口不变,这个关系的双方都是可以替换的. 一个理想的软件系 ...

  8. Network POJ - 3694 (LCA+tarjan+桥)

    题目链接:https://vjudge.net/problem/POJ-3694 具体思路:首先可以通过缩点的方式将整个图变成一个树,并且树的每条边是桥,但是我们可以利用dfn数组将整个图变成树,这样 ...

  9. php常用表单验证类用法实例

    <?php /** * 页面作用:常用表单验证类 * 作 者:欣然随风 * QQ:276624915 */ class class_post { //验证是否为指定长度的字母/数字组合 func ...

  10. spring boot 自定义属性覆盖application文件属性

    参考 Spring boot源码分析-ApplicationListener应用环境: https://blog.csdn.net/jamet/article/details/78042486 加载a ...