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. RabbitMQ的基础介绍

    转自:http://blog.csdn.net/whycold/article/details/41119807 一.引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构 ...

  2. swift4.0中http连接(据于xcode9.3 URLSession)

    NSURLSession是NSURLConnection的替代者,在2013年苹果全球开发者大会上(WWDC2013)随iOS7一起发布的,是对NSURLConnection进行了重构优化后的新的网络 ...

  3. turn服务部署

    centos7.2 git clone https://github.com/coturn/coturnyum -y install openssl-develyum install openssl ...

  4. NOIP模拟6

    期望得分:100+100+100=300 实际得分:0+100+90=190 T1 superman 二分给每条边加多少,判断是否存在负环 #include<queue> #include ...

  5. CF767 A. Snacktower 暴力

    LINK 题意:给出一个序列,如果存的数满足连续递减(第一个必须为n)则输出否则输出空行,并暂存当前数 思路:直接暴力不可行,由于待输出的数的个数满足单调性可以稍微优化,即从上一回输出的最小一个数开始 ...

  6. Centos 7 下搭建 Dokuwiki

    Centos 7 下搭建 Dokuwiki # Dokuwiki 是php的,所以要先搭建php环境,下载 apache和php,第1.2步下载完,相关的依赖都会下载## 1.下载 httpdyum ...

  7. 如何修改 winserver2008 密码策略为简单密码

    对于不在域中的计算机, 可以运行: gpedit.msc , 如下图: 对于在域中的计算机, 应该: 如不能生效, 可重启再试.

  8. 解决gridview row 左边序列号 显示不完全的技巧

    放在主程序 入口处, public Form1() { InitializeComponent(); gridView1.IndicatorWidth = ; //<宽度值>官方推荐常用是 ...

  9. Jenkins 通过ssh 拷贝文件到远程机器上。

    想实现的目的是: 在构建之前,从jenkins master上拷贝脚本到需要运行的机器上(linux ssh). 本来是通过publish over ssh 的transfer set可以直接设置,但 ...

  10. 用sqoop将mysql的数据导入到hive表中

    1:先将mysql一张表的数据用sqoop导入到hdfs中 准备一张表 需求 将 bbs_product 表中的前100条数据导 导出来  只要id  brand_id和 name 这3个字段 数据存 ...