IO流(IO Stream)

news2024/11/30 10:37:23

一、概述

我们已经系统学习了File 类,并且已经知道 File 类的实例用于表示文件或目录的路径
名。

虽然我们可以通过 File 实例来访问文件或目录的元数据,甚至可以创建、删除文件或目
录,但是,我们却不能通过File实例来访问文件中存储的内容,本节主要研究通过流来
读写数据。

为了能够 读取文件中的内容 或者 向文件中写入内容 ,就需要用到文件输入流或文件输
出流,本节将系统讲解通过流完成对文件内容的读取和写入操作。

但千万不要认为我们只能从文件中读取数据或向文件中写入数据,还有在之前我们从控制
台获取或打印到控制台以及在网络编程部分我们将会学习如何通过 Java 程序从网络
上读取数据和向网络发送数据。

1.流

Java 语言中,将够 读取数据 或者 写出数据 的对象抽象为 流。

流 类似于生活当中的 水管 , 水 可以在 水管 中 定向移动 ,正如 数据 可以在 流 中定向移
动。

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,
分为 输入input和 输出 output ,即流向内存是输入流,流出内存是输出流。

JavaI/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入也叫做读
取数据,输出也叫做作写出数据。

Java 传统的IO体系中,所有的 流 对应的类型都扩展自四个抽象类:

其中的 InputStream OutputStream 的子类表示字节流, ReaderWriter的子类则
表示字符流。

这里所提及的Stream一词均表示流,请不要与 java.util.stream.Stream 接口混为
一谈。

2.分类

Java中传统的I/O体系可以按照不同的方式对流进行分类:

  • 按照流中数据的流向来分类,可以分为 输入流 和 输出流
    - 用于实现从外部读取数据到当前程序的流被称作输入流
    - 用于实现从当前程序中向外部输出数据的流被称作输出流
  • 按照流处理的数据单元来分类,可以划分为 字节流 和 字符流
    - 如果某个流在读取或写入数据时以字节为单位,则该流属于字节流
    - 如果某个流在读取或写入数据时以字符为单位,则该流属于字符流
    - 这里纠正一下个错误,通过字符流读写字符数据时,一个字符未必就占两个字节
    - 一个字符有可能是1个字节,也可能是2个、3个、4个字节,这取决于字符编码
  • 按照流的功能来分类,可以分为 节点流 和 包装流
    - 直接数据节点中读取数据或向数据节点中写入数据的流被称作节点流
    - 数据节点可以是磁盘上的文件或其它数据源(比如键盘输入)
    - 节点流都比较原始,仅用于实现数据的读取和写入,通常不具备其它功能
    - 用于从其它流中读取数据,并实现其它流所不具备的功能的流,被称作包装流
    - 包装流也被称作 转换流 或 处理流 或 过滤流
    - 包装流通常会提供它内部所包装的流不具备的功能
    - 包装流内部所处理的流(也称作所过滤的流)被称作底层支持流
    节点流 和 包装流 的关系如下图所示:
    在这里插入图片描述

3.一切皆字节

一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都是一个一
个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时
候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

二、字节流

字节流 是以 字节 为单位读写数据的输入流或输出流。下图是Java语言中提供的 字节流
的继承体系:
在这里插入图片描述
由图可以看到, 字节流 体系中涉及的类太多,我们仅选择具有代表性的几个予以讲解,
并不是全部讲解。

1.Closeable

​java.io.Closeable 接口,实现此接口的都是可以关闭的数据的源或目的地。都会实现 c lose() 方法。如: Scanner , InputStream , OutputStream

public interface Closeable extends AutoCloseable

该类继承了 java.lang.AutoCloseable AutoCloseable 接口提供了自动关闭的能力。

2.字节输入流

2.1 InputStream

InputStream 类是所有表示字节输入流的类的父类,它是个抽象类,因此不能直接被实例
化。

public abstract class InputStream implements Closeable

InputStream 类是所有字节输入流的最顶层父类,掌握该类的使用即可从根本上把握其它
字节输入流的使用。
在这里插入图片描述

2.1.1 构造方法

InputStream 类仅有一个无参构造供子类调用:

public InputStream()

2.1.2 实例方法

在这里插入图片描述
JDK9 提供的方法:
transferTo(OutputStream out) 用于将输入流使用指定的输出流输出出去

public long transferTo(OutputStream out) throws IOException {
Objects.requireNonNull(out, "out");
long transferred = 0;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int read;
while ((read = this.read(buffer, 0, DEFAULT_BUFFER_SIZE)) >= 0) {
out.write(buffer, 0, read);
transferred += read;
}
return transferred;
}

复制文件:

package file;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo07_0912 {
    public static void main(String[] args) {
        /**
         * 将 F:\temp\test.mp4可 复制到 D:\kaifamiao\software\text\test.mp4
         * 使用`transferTo()`,将输入流的内容直接写入输出流
         */
        try {
            FileInputStream fis = new FileInputStream("F:\\test.mp4");
            FileOutputStream fos = new FileOutputStream("D:\\kaifamiao\\software\\text\\test.mp4");

            //第一种方法
//            byte[] bytes = new byte[8019];
//            int size;
//            while ((size=fis.read(bytes))!=-1){
//                fos.write(bytes,0,size);
//            }


//            //第二种方法
//            byte[] bytes = fis.readAllBytes();
//            fos.write(bytes);

            //第三种方法
            fis.transferTo(fos);

            fis.close();
            fos.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

readAllBytes()读取所有的字节(最大为 Integer.MAX_VALUE 个字节)

public byte[] readAllBytes() throws IOException {
return readNBytes(Integer.MAX_VALUE);
}

在所有方法中,仅 read() 方法是抽象方法,因此 InputStream 类的所有的子类都需要
实现该方法。
因为 InputStream 类是个抽象类,因此必须借助于其 非抽象子类 来完成实例化。
主要学习 FileInputStreamBufferedInputStream

2.2FileInputStream

FileInputStream 用于从文件系统中的某个文件中读取内容(以字节为单位)。
FileInputStream 用于读取诸如图像数据之类的原始字节流。
如需读取字符流,可以考虑使用 InputStreamReaderFileReader

public class FileInputStream extends InputStream

2.2.1 构造方法

FileInputStream 类中定义了三个公开( public )的构造方法:
在这里插入图片描述
其中较为常用的是前两个构造方法。

package com.itlaobing.demo.stream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream in = new FileInputStream("D:\\temp\\zixiafaerie.jpg");
File file = new File("D:\\temp\\zixiafaerie.jpg");
FileInputStream input = new FileInputStream(file);
}
}

2.2.2 实例方法

FileInputStream 类重写了 InputStream 类中所有的 public 方法,但除了以下方法未被重写外,其它方法均已被 FileInputStream 类所重写

public void reset() throws IOException
public void mark(int readlimit) throws IOException
public boolean markSupported() throws IOException

重写的方法包括:

public int available() throws IOException
public int read() throws IOException
public int read(byte[] bytes) throws IOException
public int read(byte[] bytes, int offset, int length) throws IOException
public long skip(long n) throws IOException
public void close() throws IOException

这里仅结合 FileInputStream 来讲解 InputStream 类中的核心方法的用法。

首先,我们创建在D:/temp目录下创建一个名称为file-input.txt的文件,其中内容如
下:

abcd1234efg
我和我的祖国
A little cold awn first, then gun out such as dragon.

然后我们分别用三种不同的方式读取该文件( D:/temp/file-input.txt )中的数据。
这里需要注意,直接在 Windows 系统中创建的 文本文档 ,其默认编码为 GBK (每个汉字
占用两个字节)。

2.2.3读取单个字节

InputStream类中定义的抽象方法是所有子类所必须实现的:

public abstract int read() throws IOException

该方法用于从字节输入流中读取单个字节;如果到达流的末尾,则返回 -1 。
而另一个方法 skip 则用于跳过指定的字节数:

public long skip(long n) throws IOException

该方法的参数 n 表示期望跳过的字节数,而返回值则表示实际所跳过的字节数。
同时, InputStream 类提供了获取流中剩余字节数的方法:

public int available() throws IOException

用于获取可以不受阻塞地从此输入流读取(或跳过)的估计字节数;如果到达输入流末
尾,则返回 0 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007808.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第六章 图 七、最短路径(BFS算法、Dijkstra算法、Floyd算法)

目录 一、BFS算法(单源最短路径) (1)介绍: (2)例子: 二、Dijkstra算法(单源最短路径) (1)介绍: (2&#…

obsstudio下载使用

官网 Open Broadcaster Software | OBS 介绍 OBS是Open Broadcaster Software的简称,是一款开源,用于视频录制以及直播串流的软件,它支持Windows、Mac以及Linux操作系统。OBS使用容易、操作简单,对于新手小白来说非常友好。如果…

集卡拖车运输最新政策调整来了_箱讯科技

国庆佳节马上就要到了,我们即将迎来一个重要的假期。 然而,对于许多进出口企业来说,国庆节并不仅仅意味着放松和庆祝,还需要提前做好出运准备。准时出运对于维护客户信任和业务运营至关重要。 伴随着国庆节的临近,运…

2000-2021年上市公司全要素生产率数据(LP法)(含原始数据、计算代码、计算结果)

2000-2021年上市公司全要素生产率数据(LP法)(含原始数据、计算代码、计算结果) 1、时间:2000-2021年 2、指标:股票代码、年份、证券代码、固定资产净额、营业总收入、营业收入、营业成本、销售费用、管理…

论文阅读之Learning and Generalization of Motor Skills by Learning from Demonstration

0、论文基本信息 DMP经典论文 论文题目:Learning and Generalization of Motor Skills by Learning from Demonstration 会议名称:2009 ICRA 论文作者:Peter Pastor, Heiko Hoffmann, Tamin Asfour and Stefan Schaal 作者简介:…

如何导出数据库数据字典

1、随便找一个工程项目,在项目build.gradle配置文件添加以下依赖 compile group: cn.smallbun.screw, name: screw-core, version: 1.0.52、刷新下载依赖 3、将以下代码拷贝到工程任意Java目录 ScrewDemo.java package com.xxx;import cn.smallbun.screw.core.C…

Manim 中文显示问题报错解决办法

使用Manim直接制作这种动画视频的话是不支持中文的,需要进行一些修改,效果如图所示。 但是修改的方案都太坑,经过自己不断的研究找到了一个比较简单实用的方法。 文章目录 源文件修改代码修改源文件修改 实用everuthing找到ctex_template.tex文件。 我这里的路径是D:\MyT…

定时器+BOM

9.定时器BOM 1.定时器 **概念:**重复执行一个函数 1.1setInterval() setInterval(“代码/函数”,时间,参数),返回定时器的序列号,默认从1开始 clearInterval(序列号)清除定时 <button class"start">开启定时器</button><button class"close…

Elasticsearch:为具有许多 and/or 高频术语的 top-k 查询带来加速

作者&#xff1a;Adrien Grand Disjunctive queries&#xff08;term_1 OR term_2 OR ... OR term_n&#xff09;非常常用&#xff0c;因此在提高查询评估效率方面它们受到了广泛关注。 Apache Lucene 对于评估 disjunctive queries 有两个主要优化&#xff1a;一方面用于详尽评…

Mac os 安装homebrew

Mac os 不会自带homebrew工具&#xff0c;而很多需要的工具需要用brew命令下载和安装&#xff0c;但是因为homebrew是国外网站&#xff0c;如果没有VPN&#xff0c;就无法下载。下面记录一下如何解决这个问题。 1、国内安装的命令如下&#xff1a; /bin/zsh -c "$(curl …

[管理与领导-89]:IT基层管理者 - 扩展技能 - 5 - 职场丛林法则 -3- 在丛林(公司->团队->个人)中定位自己

目录 前言&#xff1a; 一、了解公司市场 1.1 了解公司的途径 1.2 了解一个公司的哪些方面 1.3 商业的本质 1.4 公司的本质 1.5 公司的残酷性 1.6 公司与丛林的相似性 1.7 公司在市场中的定位涉及以下几个方面&#xff1a; 1.8 等价交换与剩余价值 在职场中的体现 二…

input输入事件

我要实现input输入框一边输入&#xff0c;一边在控制台输出结果 现有如下代码 <body><input type"text" onchange"myFunction()" /><script>function myFunction(){console.log(999)}</script> </body> 当敲下回车键后才会…

用python爬豆瓣电影《热烈》短评

一、爬虫对象-豆瓣电影短评 今天分享一期爬虫案例&#xff0c;爬取的目标是&#xff1a;豆瓣上任意一部电影的短评&#xff08;注意&#xff1a;是短评&#xff0c;不是影评&#xff01;&#xff09;&#xff0c;以《热烈》这部电影为例&#xff1a; ▲ 爬取目标 爬取以上6个…

阿里云-源码构建容器镜像

1、阿里云Code代码平台 1.1 创建访问令牌。 登录云效Codeup控制台&#xff0c;单击右上角个人设置。 在个人设置页面&#xff0c;单击左侧导航栏中的个人访问令牌。 单击创建访问令牌&#xff0c;设置配置项&#xff0c;然后单击立即创建。以下为创建访问令牌需要授予的最小权…

【C语言】【strcpy的使用和模拟实现】

1.strcpy的使用&#xff1a; char* strcpy(char* destination,const char* source)返回类型是字符指针&#xff0c;参数是接受方字符串的首地址和要拷贝的字符串的首地址 从接受地的‘\0’开始拷贝&#xff0c;会将源字符串中的’\0’也拷贝过来目标空间必须足够大&#xff0…

PASCAL VOC2012数据集以及制作自己的数据集

目录 VOC2012目录结构制作自己的数据集标注图片软件使用流程软件使用 VOC2012目录结构 制作自己的数据集 标注图片软件 github开源项目&#xff0c;形成的是xml文件格式 使用流程 软件使用

docker四种网络模式

文章目录 一.为什么要了解docker网络二.docker 网络理论三.docker的四类网络模式3.1 bridge模式3.2 host模式3.3 container模式3.4 none模式 四.bridge模式下容器的通信4.1 防火墙开启状态4.2 防火墙关闭状态 一.为什么要了解docker网络 当你开始大规模使用Docker时&#xff0…

简单讲讲在一台机器上用docker部署hadoop HDFS

为什么写这篇文章? 老东西叫我用vmvare部署hadoop,我觉得这简直蠢毙了,让我们用docker和docker-compose来快速的过一遍如何使用docker-compose来部署简单的hadoop集群范例 写在前面,一定要看我!!! 还有注意&#xff01;Hadoop中的主机名不能带-或者_ 注意了!一定注意存储空…

uboot 顶层Makefile-make xxx_deconfig过程说明三

一. uboot 的 make xxx_deconfig配置 本文接上一篇文章的内容。地址如下&#xff1a;uboot 顶层Makefile-make xxx_deconfig过程说明二_凌肖战的博客-CSDN博客 本文继续来学习 uboot 源码在执行 make xxx_deconfig 这个配置过程中&#xff0c;顶层 Makefile有关的执行思路。 …

SpringBoot临时属性简单说明

1.修改工程的端口 说明&#xff1a;将工程的端口修改成8080端口 java -jar .\springboot_09_ssmp-0.0.1-SNAPSHOT.jar --server.port8080 修改前 修改后 2.修改连接数据库密码 说明&#xff1a;修改的是application.yml中password的值 java -jar .\springboot_09_ssmp-0.0…