Java Stream简介, 流的基本概念.

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

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


一, Java中什么是Stream(流)

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

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


Java的代码如下:

import java.io.*;

public class Stream1{
    public static void f() throws IOException{
       FileReader fr = new FileReader("/home/gateman/tmp/build.xml");

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

上面的代码很简单,

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 的代码.

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

当执行碗上面的代码后,


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

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


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

这个方法需要处理IOException


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

这个也不难理解, 每读到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).




下一编 介绍留的分类以及java中的四大基本流.






  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nvd11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值