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. OpenCV---图像直方图

    一:直方图的直接使用 from matplotlib import pyplot as plt def plot_demo(image): print(image.ravel()) plt.hist( ...

  2. dubbo可通过指定Url方式绕过注册中心直连指定的服务地址

    开发.测试环境可通过指定Url方式绕过注册中心直连指定的服务地址,避免注册中心中服务过多,启动建立连接时间过长,如: <dubbo:reference id="providerServ ...

  3. 解决Ubuntu终端里面显示路径名称太长

    方法/步骤 找到配置文件先进行备份:  cp  ~/.bashrc  ~/.bashrc-bak 找到配置文件修改: vi  ~/.bashrc 备份是为了防止配置修改出错,可以还原: 下面是我的/h ...

  4. [POJ 2559]Largest Rectangle in a Histogram 题解(单调栈)

    [POJ 2559]Largest Rectangle in a Histogram Description A histogram is a polygon composed of a sequen ...

  5. php sprintf格式化注入

    URL:http://efa4e2c2b8df4ce69454639f4e3727071652c31167f341a4.game.ichunqiu.com/ 简单的说就是sprintf中%1$\'会将 ...

  6. python基础===15条变量&方法命名的最佳实践

    不同的代码段采用不同的命名长度.通常来说,循环计数器(loop counters)采用1位的单字符来命名,循环判断变量(condition/loop variables)采用1个单词来命名,方法采用1 ...

  7. python基础===python自带idle的快捷键

    Ctrl + [ Ctrl + ]   缩进代码Alt+3 Alt+4 注释.取消注释代码行Alt+5 Alt+6 切换缩进方式 空格<=>TabAlt+/ 单词完成,只要文中出现过,就可 ...

  8. 实现在点击asp:button按钮后,不刷新当前页面

    方法1:return false <asp:Button ID="Button1" runat="server" Text="Button&qu ...

  9. Machine Learning系列--深入理解拉格朗日乘子法(Lagrange Multiplier) 和KKT条件

    在求取有约束条件的优化问题时,拉格朗日乘子法(Lagrange Multiplier) 和KKT条件是非常重要的两个求取方法,对于等式约束的优化问题,可以应用拉格朗日乘子法去求取最优值:如果含有不等式 ...

  10. The hub and spoke model 轮辐模型/辐射模型

    最近一些文档中提到The Hub and Spoke Model,这里mark一下.hub表示轮毂,spoke表示轮辐,轮辐模型是简化网络路由的一套中心化的体系,广泛应用于航空.货运.快递以及网络技术 ...