广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java基础:流Stream详解
  • 707
分享到

Java基础:流Stream详解

2024-04-02 19:04:59 707人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录写在前面一、"流"概念二、流的分类1、按流的方向分为:输入流、输出流2、按流处理数据的单位分为:字节流、字符流3、按流的功能分为:节点流(又称低级流)、过滤流(又称高级流、处理流

写在前面

从Java 1.0开始,引入java.io包;到Java 1.4再扩展了java.NIO包;再到java 1.7又添加了新的流类,使得Java的流机制变得十分强大。

一、"流"概念

James Gosling所著《Java程序设计》中描述Java I/O流模式图如下。Program是中间环节,用于对Source进行处理,然后输出到Dest处。

b654b83fa3312585d665d043388b518d.png

Java中的"流"就是指把数据从一个对象移动到另一个对象的流动模式的抽象。其实Java的流模式用水流或者电流模型来解释是很容易理解的。

363cc7573ed96e3ea734d47025759159.png

James Gosling的Java流模式图与水流模式图概念映射。数据源(data source)即水库,数据目的地(data destination)就是脸盆,数据(data)就是水,流(stream)实例化就是在管子中流动的水流。

输入流(input stream)就是用水泵从水库中抽出来要到水管中的水,输出流(output stream)经过水龙头将要达到脸盆中的水,计算机内存(memory)就是上图中的水流管道,关闭输入流(close input stream)就是关闭水泵开关,关闭输出流(close output stream)就是关闭关闭水龙头开关。

更进一步说,具体的水库和脸盆分别对应于Java中输入流对象和输出流对象。水流可以分成一粒一粒的水分子,这些水分子映射成计算机二进制位(bit)0/1,其组成的水滴映射成计算机字节流(字节是计算机储存信息的基本单位)。字节流和字符流在物理层面的实现都是比特流,二进制数据流可以认为是字节流,而字符流是遵循unicode编码规则的字节流。因此计算机中的"流"概念实际上就是指字节数据(bytes data)从源对象对按顺序流向目标对象的一种流动形式。

e31533f5a5cfd51c65279543be6e302a.png

二、流的分类

1、按流的方向分为:输入流、输出流

判断当前流是输入流还是输出流的依据是二进制数据相对于计算机内存的位置,输入流是输入计算机内存是二进制数据,输出流是从计算机内存输出的二进制数据。而计算机程序在运行期间会储存在到计算机内存中,因此总的来说就是数据的来源、取向是相对程序而言的。比如键盘键入数据属于输入流,内存数据持久化到磁盘中属于输出流。

cd73d9ac40fe5f303e72def8f682ddf4.png

说明:本图片取自互联网,纠正补充为流的来源有网络连接、内存块、磁盘(文件)、键盘等;流的去向也基本是这些。

2、按流处理数据的单位分为:字节流、字符流

从物理层面来看,流中数据都是二进制比特流。而计算机中储存信息的基本单位是字节(Byte)。因此,可以认为计算机中信息传输在底层是靠字节流来实现的。字符流只是通过不同的字符编码方式,对字节流的封装,即字符流的实现还是得依靠字节流。

3、按流的功能分为:节点流(又称低级流)、过滤流(又称高级流、处理流、包装流)

节点流(node Stream)是流管道两端直接连接data source和data destination上的,即为取放数据的真实载体,在流通道本身不对数据做任何加工,因而也被称为低级流。

节点流从一个特定的数据源读写数据。即节点流是直接操作文件,网络等的流,例如FileInputStream和FileOutputStream,他们直接从文件中读取或往文件中写入字节流。

2374f1b0340903f7b84a7a89c3f94422.png

“连接”在已存在的流(节点流或处理流)之上通过对数据的处理为程序提供更为强大的读写功能。过滤流是使用一个已经存在的输入流或输出流连接创建的,过滤流就是对节点流进行一系列的包装。例如BufferedInputStream和BufferedOutputStream,使用已经存在的节点流来构造,提供带缓冲的读写,提高了读写的效率,以及DataInputStream和DataOutputStream,使用已经存在的节点流来构造,提供了读写Java中的基本数据类型的功能。他们都属于过滤流。

f71da4ab9fa8bc1a96224fc34c9d1ad0.png


public static void main(String[] args) throws IOException {
        // 节点流FileOutputStream直接以A.txt作为数据源操作
        FileOutputStream fileOutputStream = new FileOutputStream("A.txt");
        // 过滤流BufferedOutputStream进一步装饰节点流,提供缓冲写
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(
                fileOutputStream);
        // 过滤流DataOutputStream进一步装饰过滤流,使其提供基本数据类型的写
        DataOutputStream out = new DataOutputStream(bufferedOutputStream);
        out.writeInt(3);
        out.writeBoolean(true);
        out.flush();
        out.close();
        // 此处输入节点流,过滤流正好跟上边输出对应,读者可举一反三
        DataInputStream in = new DataInputStream(new BufferedInputStream(
                new FileInputStream("A.txt")));
        System.out.println(in.readInt());
        System.out.println(in.readBoolean());
        in.close();
}

理解:

  • FileOutputStream是根据二进制010101一个一个字节处理
  • BufferedOutputStream是对字节封装成buffered,以缓冲区处理
  • DataOutputStream是以字符串形式,类似(“hello”)处理。

4、字节流与字符流区别

  • 字节流默认是不带缓冲区的,而字符流默认是带缓冲区的。
  • 字节流是底层数据流,是数据有意义的最小单位。字符流是字节流的包装,底层实现是字节流。
  • 字节流读取的时候,读到一个字节就返回一个字节;字符流使用了字节流读到一个或多个字节(中文对应的字节数是两个,在UTF-8码表中是3个字节)时。先去查指定的编码表,将查到的字符返回。
  • 字节流可以处理所有类型数据,如:图片,MP3,AVI视频文件,而字符流只能处理字符数据。只要是处理纯文本数据,就要优先考虑使用字符流,除此之外都用字节流。文本文件可以用字节流来实现,当然使用字符流速度会更快。

三、流的方法

1、字节流

字节输入流类:FileInputStream、BufferedInputStream和DataInputStream

FileInputStream:此类用于从本地文件系统中读取文件内容。

构造方法:

  • FileInputStream(File file):打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的File对象file指定。
  • FileInputStream(String name):打开一个到实际文件的连接来创建一个FileInputStream,该文件通过文件系统中的路径名name指定。

常用方法:

  • int available():返回下一次对此输入流调用的方法不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
  • void close():关闭此文件输入流并释放与该流关联的所有系统资源。

BufferedInputStream此类本身带有一个缓冲区,在读取数据时,先放到缓冲区中,可以减少对数据源的访问,提高运行的效率。

构造方法:

  • BufferedInputStream(InputStream in):创建一个BufferedInputStream并保存其参数,即输入流in,以便将来使用。
  • BufferedInputStream(InputStream in,int size):创建一个具有指定缓冲区大小的BufferedInputStream并保存其参数,即输入流in,以便将来使用。

常用方法:

  • int available():返回下一次对此输入流调用的方法不受阻塞地从此输入流读取(或跳过)的估计剩余字节数。
  • void close():关闭此输入流并释放与该流关联的所有系统资源。
  • int read():从输入流中读取数据的下一个字节。
  • int read(byte[] b,int off,int len):从此字节输入流中给定偏移量处开始将各字节读取到指定的byte数组中。

DataInputStream:该类提供一些基于多字节读取方法,从而可以读取基本数据类型的数据。

构造方法:

  • DataInputStream(InputStream in):使用指定的底层InputStream创建一个DataInputStream。

常用方法:

  • int read(byte[] b):从包含的输入流中读取一定数量的字节,并将它们存储到缓冲区数组b中。
  • int read(byte[] b,int off,int len):从包含的输入流中将最多len个字节读入一个byte数组中。

字节输出流类:FileOutputStream、BufferedOutputStream和DataOutputStream

FileOutputStream:此类用于从本地文件系统的文件中写入数据。

构造方法:

  • FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流。FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流。

常用方法:

  • void close():关闭此文件输出流并释放与此流有关的所有系统资源。
  • FileDescriptor getFD():返回与此流有关的文件描述符。
  • void write(byte[] b):将b.length个字节从指定byte数组写入此文件输出流中。
  • void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此文件输出流。
  • void write(int b):将指定字节写入此文件输出流。

BufferedOutputStream:此类本身带有一个缓冲区,在写入数据时,先放到缓冲区中,实现缓冲的数据流。

构造方法:

  • BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,来将数据写入指定的底层输入流。
  • BufferedOutputStream(OutputStream out,int size):创建一个新的缓冲输出流,来将具有指定缓冲区大小的数据写入指定的底层输出流。

常用方法:

  • void flush():刷新此缓冲的输出流。
  • void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入此缓冲的输出流。
  • void write(int b):将指定的字节写入此缓冲的输出流。

DataOutputStream(OutputStream out):创建一个新的数据输出流,将数据写入指定基础输出流。

常用方法:

  • void flush():清空此数据输出流。
  • int size():返回计数器written的当前值,即到目前为止写入此数据输出流的字节数。
  • void write(byte[] b,int off,int len):将指定byte数组中从偏移量off开始的len个字节写入基础输出流。
  • void write(int b):将指定字节(参数b的八个低位)写入基础输出流。

2、字符流

FileReader:用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的

构造方法:

FileReader(File file):在给定从中读取数据的File的情况下创建一个新的FileReader。FileReader(String fileName):在给定从中读取数据的文件名的情况下创建一个新的FileReader。

BufferedReader类是Reader类的子类,为Reader对象添加字符缓冲器,为数据输入分配内存存储空间,存取数据更为有效。

构造方法:

  • BufferedReader(Reader in):创建一个使用默认大小输入缓冲区的缓冲字符输入流。
  • BufferedReader(Reader in,int sz):创建一个使用指定大小输入缓冲区的缓冲字符输入流。

操作方法:

  • void close():关闭该流并释放与之关联的所有资源。
  • void mark(int readAheadLimit):标记流中的当前为止。
  • boolean markSupported();判断此流是否支持mark()操作。
  • int read():读取单个字符。
  • int read(char[] cbuf,int off,int len):将字符读入数组的某一部分。
  • String readLine():读取一个文本行。
  • boolean ready():判断此流是否已准备好被读取。
  • void reset():将流重置到最新的标记。
  • long skip(long n):跳过字符。

FileWriter:用来写入字符文件的便捷类,可用于写入字符流。

构造方法:

FileWriter(File file):根据给定的File对象构造一个FileWriter对象。

FileWriter(String filename):根据给定的文件名构造一个FileWriter对象。

BufferedWriter: 将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。

缓冲流的目的:

操作流的时候,习惯定义一个byte/char数组。

int read(): 每次都从磁盘文件中读取一个字节。 直接操作磁盘文件性能极低。

解决方案:定义一个数组作为缓冲区。

byte[] buffer = new byte[1024];该数组其实就是一个缓冲区。

一次性从磁盘文件中读取1024个字节。如此以来,操作磁盘文件的次数少了,性能得以提升。提供的默认缓存区大小是8192(1024*8),我们一般不用修改大小


public class BufferStreamDemo {
    public static void main(String[] args) throws Exception {
        File file = new File("file/aaa.txt");
        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
        out.write("中国".getBytes());
        out.close();
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        byte[] buffer = new byte[1024];
        int len = -1;
        while((len = in.read(buffer)) != -1){
            System.out.println(new String(buffer, 0, len));
        }
        in.close();
    }
}
public class BufferCharacterDemo {
    public static void main(String[] args) throws Exception {
        File file = new File("file/aaa.txt");
        BufferedWriter in = new BufferedWriter(new FileWriter(file,true));
        in.newLine();//用来换行等同于‘\n'
        in.write("美国");
        in.newLine();
        in.write("马来西亚");
        in.close();
        BufferedReader out = new BufferedReader(new FileReader(file));
        String line = null;
        //按行读取
        while((line = out.readLine()) != null){
            System.out.println(line);
        }
        out.close();
    }
}

4、流相关设计模式

处理流/包装流(相对于节点流更高级) 装饰设计模式/包装模式:

  • 隐藏了底层的节点流的差异,并对外提供了更方便的输入/输出功能,让我们只关心高级流的操作.
  • 使用处理流包装了节点流,程序直接操作处理流,让节点流与底层的设备做IO操作.
  • 只需要关闭处理流即可.

参考:https://blog.csdn.net/dreamzuora/article/details/79691702

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!

--结束END--

本文标题: Java基础:流Stream详解

本文链接: https://www.lsjlt.com/news/136055.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java基础:流Stream详解
    目录写在前面一、"流"概念二、流的分类1、按流的方向分为:输入流、输出流2、按流处理数据的单位分为:字节流、字符流3、按流的功能分为:节点流(又称低级流)、过滤流(又称高级流、处理流...
    99+
    2022-11-12
  • 【Java 基础篇】Java Stream流详解
    文章目录 导言一、Stream流的概念二、Stream流的使用方法三、并行流操作四、Stream流与集合的比较总结 导言 Java Stream流是Java 8引入的一种新的数据处理方...
    99+
    2023-09-11
    java
  • Java基础之Stream流原理与用法详解
    目录一、接口设计二、创建操作三、中间操作四、最终操作五、Collect收集Stream简化元素计算 一、接口设计 从Java1.8开始提出了Stream流的概念,侧重对于源数据计算能...
    99+
    2022-11-13
    Java Stream流 原理 Java Stream流 用法 Java Stream流
  • Java Stream流详解
    本文目录 学习目标中间操作Filter(过滤)Map(转换)Sorted(排序)Distinct(去重)Limit(限制)Skip(跳过)Peek(展示) 终止操作forEach(循环)Collect(收集)Count(计数)R...
    99+
    2023-08-16
    java 开发语言 stream流
  • Java--Stream流详解
    Stream是Java 8 API添加的一个新的抽象,称为流Stream,以一种声明性方式处理数据集合(侧重对于源数据计算能力的封装,并且支持序列与并行两种操作方式) Stream流是从支持数据处理操作的源生成的元素序列,源可以是数组、...
    99+
    2023-08-31
    stream
  • Java中Stream流详解
    今天在Java学习中,遇到了starm这个操作方式,了解后发现很多操作都很实用并且在项目开发中经常用到,特写下此篇博客用来记录。 目录 一、Stream基础概念Stream操作中的惰性计算创建Stream 二、常用的Strea...
    99+
    2023-08-25
    java 开发语言 jvm
  • Java基础之FileInputStream和FileOutputStream流详解
    目录一、前言二、创建流对象三、FileInputStream常用方法四、FileOutputStream常用方法五、输入输出流测试代码一、前言 FileInputStream 用于读...
    99+
    2022-11-12
  • Java的Stream流详细讲解
    一.Stream 是什么 Stream是Java 8新增的重要特性, 它提供函数式编程支持并允许以管道方式操作集合. 流操作会遍历数据源, 使用管道式操作处理数据后生成结果集合, 这个过程通常不会对数据源造成影响。 ​ 同时stream不是...
    99+
    2023-08-31
    java 开发语言
  • java基础理论Stream管道流Map操作示例
    目录一、回顾Stream管道流map的基础用法二、处理非字符串类型集合元素三、再复杂一点:处理对象数据格式转换四、flatMap一、回顾Stream管道流map的基础用法 最简单的需...
    99+
    2022-11-13
  • JAVA中stream流的基础处理方法有哪些
    这篇文章主要介绍了JAVA中stream流的基础处理方法有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JAVA中stream流的基础处理方法有哪些文章都会有所收获,下面我们一起来看看吧。Stream流程处...
    99+
    2023-07-05
  • Java Stream流语法示例详解
    目录如何使用StreamStream的操作分类1、创建流2、操作流1)过滤2)映射3)匹配4)组合3、转换流如何使用Stream 聚合操作是Java 8针对集合类,使编程更为便利的方...
    99+
    2022-11-13
  • Java流处理stream使用详解
    目录基本流中间操作与终端操作一些常见的终端操作进阶流筛选各异的元素截断跳过元素映射流mapflatMap匹配全匹配与非全匹配OptionalfindAnyfindFirst归约求和归...
    99+
    2022-11-13
  • 【Java基础】- HttpURLConnection详解
    【Java基础】- HttpURLConnection详解 文章目录 【Java基础】- HttpURLConnection详解一、HttpURLConnection简述二、HttpURLCo...
    99+
    2023-09-09
    java servlet 开发语言 HttpURL
  • Java 8 Stream API 基础教程
    作者:禅与计算机程序设计艺术 1.简介 1995年4月1日,Java编程语言问世,被广泛应用于各个领域。Java平台提供了面向对象的编程能力、安全性、健壮性和可移植性。作为第一个支持动态类型和自动内存...
    99+
    2023-10-09
    自然语言处理 人工智能 语言模型 编程实践 开发语言 架构设计
  • 【Stream流】java中Stream流详细使用方法
    在Java中,Stream是一种用于处理集合数据的流式操作API。它提供了一种简洁、灵活、高效的方式来对集合进行各种操作,如过滤、映射、排序等。下面是一些Stream的常用功能和详细的代码示例: 创...
    99+
    2023-09-29
    java spring boot 后端 开发语言
  • 【Java 基础篇】Java Set 详解
    文章目录 导言一、Set 概述二、HashSet三、TreeSet四、LinkedHashSet总结 导言 在Java的集合框架中,Set接口是一个无序、不可重复的集合,它扩展了Col...
    99+
    2023-10-18
    java 开发语言 数据结构
  • 【Java 基础篇】Java List 详解
    文章目录 导言一、List 概述二、ArrayList三、LinkedList四、Vector总结 导言 在Java的集合框架中,List接口是一个有序、可重复的集合,它扩展了Coll...
    99+
    2023-09-11
    java list 数据结构
  • 【Java 基础篇】Java Collection详解
    文章目录 导言一、Collection 简介二、List 接口三、Set 接口四、Map 接口总结 导言 Java的Collection框架是一组用于存储和操作对象的接口和类。它提供了...
    99+
    2023-09-14
    java 开发语言 jvm
  • 【Java 基础篇】Java Map 详解
    文章目录 导言一、Map 概述二、HashMap三、TreeMap四、LinkedHashMap总结 导言 在Java的集合框架中,Map接口用于存储键值对,提供了一种基于键进行查找和操作的数据结构。Map接口的实现类提供了...
    99+
    2023-08-30
    java 开发语言 数据结构
  • Java基础之Maven详解
    目录一、Maven环境的搭建1. 为什么要学习Maven?2. Maven项目架构管理工具3. 下载安装Maven4. 配置环境变量5. 阿里云...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作