Java字节流的使用

InputStream 是 Java 所有字节输入流类的父类,OutputStream 是 Java 所有字节输出流类的父类,它们都是一个抽象类,因此继承它们的子类要重新定义父类中的抽象方法。

下面首先介绍上述两个父类提供的常用方法,然后介绍如何使用它们的子类输入和输出字节流,包括 ByteArrayInputStream 类、ByteArrayOutputStream 类、FileInputStream 类和 FileOutputStream 类。

字节输入流

InputStream 类及其子类的对象表示字节输入流,InputStream 类的常用子类如下。

	ByteArrayInputStream 类:将字节数组转换为字节输入流,从中读取字节。FileInputStream 类:从文件中读取数据。PipedInputStream 类:连接到一个 			PipedOutputStream(管道输出流)。SequenceInputStream 类:将多个字节输入流串联成一个字节输入流。ObjectInputStream 类:将对象反序列化。

使用 InputStream 类的方法可以从流中读取一个或一批字节。

InputStream类的常用方法

方法名及返回值类型说明
int read()从输入流中读取一个 8 位的字节,并把它转换为 0~255 的整数,最后返回整数。如果返回 -1,则表示已经到了输入流的末尾。为了提高 I/O 操作的效率,建议尽量使用 read() 方法的另外两种形式
int read(byte[] b)从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。 该方法返回读取的字节数。如果返回 -1,则表示已经到了输入流的末尾
int read(byte[] b, int off, int len)从输入流中读取若干字节,并把它们保存到参数 b 指定的字节数组中。其中,off 指定在字节数组中开始保存数据的起始下标;len 指定读取的字节数。该方法返回实际读取的字节数。如果返回 -1,则表示已经到了输入流的末尾
void close()关闭输入流。在读操作完成后,应该关闭输入流,系统将会释放与这个输入流相关的资源。注意,InputStream 类本身的 close() 方法不执行任何操作,但是它的许多子类重写了 close() 方法
int available()返回可以从输入流中读取的字节数
long skip(long n)从输入流中跳过参数 n 指定数目的字节。该方法返回跳过的字节数
void mark(int readLimit)在输入流的当前位置开始设置标记,参数 readLimit 则指定了最多被设置标记的字节数
boolean markSupported()判断当前输入流是否允许设置标记,是则返回 true,否则返回 false
void reset()将输入流的指针返回到设置标记的起始处

注意:在使用 mark() 方法和 reset() 方法之前,需要判断该文件系统是否支持这两个方法。

字节输出流

OutputStream 类及其子类的对象表示一个字节输出流。OutputStream 类的常用子类如下。

	ByteArrayOutputStream 类:向内存缓冲区的字节数组中写数据。FileOutputStream 类:向文件中写数据。PipedOutputStream 类:连接到一个 		PipedlntputStream(管道输入流)。ObjectOutputStream 类:将对象序列化。

利用 OutputStream 类的方法可以从流中写入一个或一批字节。

OutputStream 类的常用方法

方法名及返回值类型说明
void write(int b)向输出流写入一个字节。这里的参数是 int 类型,但是它允许使用表达式,而不用强制转换成 byte 类型。为了提高 I/O 操作的效率,建议尽量使用write() 方法的另外两种形式
void write(byte[] b)把参数 b 指定的字节数组中的所有字节写到输出流中
void write(byte[] b,int off,int len)把参数 b 指定的字节数组中的若干字节写到输出流中。其中,off 指定字节数组中的起始下标,len 表示元素个数
void close()关闭输出流。写操作完成后,应该关闭输出流。系统将会释放与这个输出流相关的资源。注意,OutputStream 类本身的 close() 方法不执行任何操作,但是它的许多子类重写了 close() 方法
void flush()为了提高效率,在向输出流中写入数据时,数据一般会先保存到内存缓冲区中,只有当缓冲区中的数据达到一定程度时,缓冲区中的数据才会被写入输出流中。使用 flush() 方法则可以强制将缓冲区中的数据写入输出流,并清空缓冲区

字节数组输入流

ByteArrayInputStream 类可以从内存的字节数组中读取数据,该类有如下两种构造方法重载形式

	ByteArrayInputStream(byte[] buf):创建一个字节数组输入流,字节数组类型的数据源由参数 buf 指定。ByteArrayInputStream(byte[] buf,int offse,int length):创建一个字节数组输入流,其中,参数 buf 指定字节数组类型的数据源,offset 指定在数组中开始读取数据的起始下标位置,length 指定读取的元素个数。

使用 ByteArrayInputStream 类实现从一个字节数组中读取数据,再转换为 int 型进行输出。代码如下:

public class test {public static void main(String[] args) {byte[] b = new byte[] { 1, -1, 25, -22, -5, 23 }; // 创建数组ByteArrayInputStream bais = new ByteArrayInputStream(b, 0, 6); // 创建字节数组输入流int i = bais.read(); // 从输入流中读取下一个字节,并转换成int型数据while (i != -1) { // 如果不返回-1,则表示没有到输入流的末尾System.out.println("原值=" + (byte) i + "\t\t\t转换为int类型=" + i);i = bais.read(); // 读取下一个}}
}

上例中,字节输入流 bais 从字节数组 b 的第一个元素开始读取 4 字节元素,并将这 4 字节转换为 int 类型数据,最后返回。

提示:上述示例中除了打印 i 的值外,还打印出了 (byte)i 的值,由于 i 的值是从 byte 类型的数据转换过来的,所以使用 (byte)i 可以获取原来的 byte 数据。

该程序的运行结果如下:

原值=1   转换为int类型=1
原值=-1   转换为int类型=255
原值=25   转换为int类型=25
原值=-22   转换为int类型=234
原值=-5   转换为int类型=251
原值=23   转换为int类型=23

从结果可以看出,字节类型的数据 -1 和 -22 转换成 int 类型的数据后变成了 255 和 234,对这种结果的解释如下:

	字节类型的 1,二进制形式为 00000001,转换为 int 类型后的二进制形式为 00000000 00000000 0000000000000001,对应的十进制数为 1。字节类型的 -1,二进制形式为 11111111,转换为 int 类型后的二进制形式为 00000000 00000000 0000000011111111,对应的十进制数为 255。

可见,从字节类型的数转换成 int 类型的数时,如果是正数,则数值不变;如果是负数,则由于转换后,二进制形式前面直接补了 24 个 0,这样就改变了原来表示负数的二进制补码形式,所以数值发生了变化,即变成了正数。

提示负数的二进制形式以补码形式存在,例如 -1,其二进制形式是这样得来的:首先获取 1 的原码 00000001,然后进行反码操作,1 变成 0,0 变成 1,这样就得到 11111110,最后进行补码操作,就是在反码的末尾位加 1,这样就变成了 11111111。

字节数组输出流

ByteArrayOutputStream 类可以向内存的字节数组中写入数据,该类的构造方法有如下两种重载形式。

	ByteArrayOutputStream():创建一个字节数组输出流,输出流缓冲区的初始容量大小为 32 字节。ByteArrayOutputStream(int size):创建一个字节数组输出流,输出流缓冲区的初始容量大小由参数 size 指定。

ByteArrayOutputStream 类中除了有前面介绍的字节输出流中的常用方法以外,还有如下两个方法。

	intsize():返回缓冲区中的当前字节数。byte[] toByteArray():以字节数组的形式返回输出流中的当前内容。

使用 ByteArrayOutputStream 类实现将字节数组中的数据输出,代码如下所示。

public class Test {public static void main(String[] args) {ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] b = new byte[] { 1, -1, 25, -22, -5, 23 }; // 创建数组baos.write(b, 0, 6); // 将字节数组b中的前4个字节元素写到输出流中System.out.println("数组中一共包含:" + baos.size() + "字节"); // 输出缓冲区中的字节数byte[] newByteArray = baos.toByteArray(); // 将输出流中的当前内容转换成字节数组System.out.println(Arrays.toString(newByteArray)); // 输出数组中的内容}
}

该程序的输出结果如下:

数组中一共包含:6字节
[1, -1, 25, -22, -5, 23]

文件输入流

FileInputStream 是 Java 流中比较常用的一种,它表示从文件系统的某个文件中获取输入字节。通过使用 FileInputStream 可以访问文件中的一个字节、一批字节或整个文件。

在创建 FileInputStream 类的对象时,如果找不到指定的文件将拋出 FileNotFoundException 异常,该异常必须捕获或声明拋出。

FileInputStream 常用的构造方法主要有如下两种重载形式。

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

示例 FileInputStream() 两个构造方法的使用。

try {// 以File对象作为参数创建FileInputStream对象FileInputStream fis1 = new FileInputStream(new File("F:/mxl.txt"));// 以字符串值作为参数创建FilelnputStream对象FileInputStream fis2 = new FileInputStream("F:/mxl.txt");
} catch(FileNotFoundException e) {System.out.println("指定的文件找不到!");
}

假设有一个 D:\myJava\HelloJava.java 文件,下面使用 FileInputStream 类读取并输出该文件的内容。代码如下:

public class Test {public static void main(String[] args) {File f = new File("D:/myJava/HelloJava.java");FileInputStream fis = null;try {// 因为File没有读写的能力,所以需要有个InputStreamfis = new FileInputStream(f);// 定义一个字节数组byte[] bytes = new byte[1024];int n = 0; // 得到实际读取到的字节数System.out.println("D:\\myJava\\HelloJava.java文件内容如下:");// 循环读取while ((n = fis.read(bytes)) != -1) {String s = new String(bytes, 0, n); // 将数组中从下标0到n的内容给sSystem.out.println(s);}} catch (Exception e) {e.printStackTrace();} finally {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}
}

如上述代码,在 FileInputDemo 类的 main() 方法中首先创建了一个 File 对象 f,该对象指向 D:\myJava\HelloJava.java 文件。接着使用 FileInputStream 类的构造方法创建了一个 FileInputStream 对象 fis,并声明一个长度为 1024 的 byte 类型的数组,然后使用 FileInputStream 类中的 read() 方法将 HelloJava.java 文件中的数据读取到字节数组 bytes 中,并输出该数据。最后在 finally 语句中关闭 FileInputStream 输入流。

D:\myJava\HelloJava.java文件内容如下:

/*
*第一个java程序
*/
public class HelloJava {// 这里是程序入口public static void main(String[] args) {// 输出字符串System.out.println("你好 Java");}
}

注意:FileInputStream 类重写了父类 InputStream 中的 read() 方法、skip() 方法、available() 方法和 close() 方法,不支持 mark() 方法和 reset() 方法。

文件输出流

FileOutputStream 类继承自 OutputStream 类,重写和实现了父类中的所有方法。FileOutputStream 类的对象表示一个文件字节输出流,可以向流中写入一个字节或一批字节。在创建 FileOutputStream 类的对象时,如果指定的文件不存在,则创建一个新文件;如果文件已存在,则清除原文件的内容重新写入。

FileOutputStream 类的构造方法主要有如下 4 种重载形式。

	FileOutputStream(File file):创建一个文件输出流,参数 file 指定目标文件。FileOutputStream(File file,boolean append):创建一个文件输出流,参数 file 指定目标文件,append 指定是否将数据添加到目标文件的内容末尾,如果为 true,则在末尾添加;如果为 false,则覆盖原有内容;其默认值为 false。FileOutputStream(String name):创建一个文件输出流,参数 name 指定目标文件的文件路径信息。FileOutputStream(String name,boolean append):创建一个文件输出流,参数 name 和 append 的含义同上。

注意:使用构造方法 FileOutputStream(String name,boolean append) 创建一个文件输出流对象,它将数据附加在现有文件的末尾。该字符串 name 指明了原文件,如果只是为了附加数据而不是重写任何已有的数据,布尔类型参数 append 的值应为 true。

对文件输出流有如下四点说明:
1 . 在 FileOutputStream 类的构造方法中指定目标文件时,目标文件可以不存在。

2 . 目标文件的名称可以是任意的,例如 D:\abc、D:\abc.de 和 D:\abc.de.fg 等都可以,可以使用记事本等工具打开并浏览这些文件中的内容。

3 . 目标文件所在目录必须存在,否则会拋出 java.io.FileNotFoundException 异常。

4 . 目标文件的名称不能是已存在的目录。例如 D 盘下已存在 Java 文件夹,那么就不能使用 Java 作为文件名,即不能使用 D:\Java,否则抛出 java.io.FileNotFoundException 异常。

读取 D:\myJava\HelloJava.java 文件的内容,在这里使用 FileInputStream 类实现,然后再将内容写入新的文件 D:\myJava\HelloJava.txt 中。具体的代码如下:

public class Test {public static void main(String[] args) {FileInputStream fis = null; // 声明FileInputStream对象fisFileOutputStream fos = null; // 声明FileOutputStream对象fostry {File srcFile = new File("D:/myJava/HelloJava.java");fis = new FileInputStream(srcFile); // 实例化FileInputStream对象File targetFile = new File("D:/myJava/HelloJava.txt"); // 创建目标文件对象,该文件不存在fos = new FileOutputStream(targetFile); // 实例化FileOutputStream对象byte[] bytes = new byte[1024]; // 每次读取1024字节int i = fis.read(bytes);while (i != -1) {fos.write(bytes, 0, i); // 向D:\HelloJava.txt文件中写入内容i = fis.read(bytes);}System.out.println("写入结束!");} catch (Exception e) {e.printStackTrace();} finally {try {fis.close(); // 关闭FileInputStream对象fos.close(); // 关闭FileOutputStream对象} catch (IOException e) {e.printStackTrace();}}}
}

如上述代码,将 D:\myJava\HelloJava.java 文件中的内容通过文件输入/输出流写入到了 D:\myJava\HelloJava.txt 文件中。由于 HelloJava.txt 文件并不存在,所以在执行程序时将新建此文件,并写入相应内容。

运行程序,成功后会在控制台输出“写入结束!”。此时,打开 D:\myJava\HelloJava.txt 文件会发现,其内容与 HelloJava.java 文件的内容相同。

提示:在创建 FileOutputStream 对象时,如果将 append 参数设置为 true,则可以在目标文件的内容末尾添加数据,此时目标文件仍然可以暂不存在。

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

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

相关文章

ARMA模型的性质之方法性工具

目录 一、差分 Xt 二、延迟算子 延迟算子的性质 p阶差分 k步差分 三、线性差分方程 齐次线性差分方程的解 非齐次线性差分方程的解 时序分析与线性差分方程的关系 一、差分 Xt 二、延迟算子 延迟算子类似于一个时间指针,当前序列值乘以一个延迟算子&…

python如何下载库_python中如何下载库

python下载安装库的方法: 1、在线安装 在cmd窗口直接运行:pip install 包名,如 pip install requests 注意:这种方式安装时会自动下载第三方库,安装完成后并不会删除,如需删除请到它的默认下载路径下手动删…

Java字符流的使用

字符输入流 Reader 类是所有字符流输入类的父类,该类定义了许多方法,这些方法对所有子类都是有效的。 Reader 类的常用子类如下。 CharArrayReader 类:将字符数组转换为字符输入流,从中读取字符。StringReader 类:将…

ARMA模型的性质 1

目录 1.wold分解定理(1938) 2.AR模型 2.1定义: AR(p) 有三个限制条件: 中心化 AR(p) 模型 2.2 AR模型的平稳性判别 序列拟合函数 R 举例 1.wold分解定理(1938) 对于任何一个离散平稳序列 {xt} 他都…

python 二维码_Python提取支付宝和微信支付二维码

本文首发于我的个人博客,更多 Python 和 django 开发教程,请访问 追梦人物的博客。支付宝或者微信支付导出的收款二维码,除了二维码部分,还有很大一块背景图案,例如下面就是微信支付的收款二维码:有时候我们…

Java转换流

一般情况下,字节流可以对所有的数据进行操作,但是有些时候在处理一些文本时我们要用到字符流,比如,查看文本的中文时就是需要采用字符流更为方便。所以 Java IO 流中提供了两种用于将字节流转换为字符流的转换流。 InputStreamRe…

ARMA模型的平稳性判别(续)

目录 1.特征根判别法 AR(p)模型对应齐次方程特征根与回归系数多项式根的关系: 2.平稳域判别 (1)AR(1)(一阶)模型平稳域 (2)AR(2)(二阶)模型平稳域 3.举例 4.函数展开成幂级数——麦克劳林级数 小结 1.特征根判…

form表单中根据值判断是否disabled_Java 0基础入门 (Html表单、表单元素)

上一篇:Java 0基础入门 (Html标签的使用)表单在网页中主要负责数据采集功能。一.表单实际应用场景百度搜索5173注册如上两张图,图中的黑色线条是我画上去的,如果按照黑线,在Excle中画出这两张表单,相信大家都可以也不是…

ARMA模型性质之平稳AR模型得统计性质

目录 1.均值 Green函数定义 Green函数递推公式 2.方差 举例: 方法1: 方法2: 3.协方差函数 举例1: 举例2: 4.自相关系数 常用的ARA模型自相关系数递推公式: AR模型自相关系数的性质 举例 5.偏自…

Java存储图书信息

使用文件输入/输出流完成存储图书并将图书信息再读取出来的功能。 每到学校开学季都会新进一批图书教材,需要将这些图书信息保存到文件,再将它们打印出来方便老师查看。下面编写程序,使用文件输入/输出流完成图书信息的存储和读取功能&#…

LDA(线性判别分析(普通法))详解 —— python

在这里和大家道个歉,因为我有一篇matlab的LDA和这篇内容大致相同,我就犯懒了,直接复制,没想到公式复制过来全变成了图片,然后造成了,排版有问题,非常难看,真的很抱歉!&am…

wordpress 通过域名无法访问_VPS主机和宝塔面板搭建WordPress网站教程

这是一篇Wordpress建站教程,记录了我在VPS主机上,通过使用宝塔面板,搭建Wordpress网站或个人博客的详细步骤,外贸新人或小白在建立网站的时候可以作为参考。WordPress是全球最流行的建站程序,而且是免费的。用Wordpres…

猜数字小游戏

java代码 猜数字小游戏 程序分析 根据提示输入内容 获取输入的内容 使用for循环进行遍历使用if循坏进行数值的判断 输出结果 完整代码 import java.util.Scanner; import java.util.Random; public class mulTip{public static void main(String[] args){System.out.println…

LDA(线性判别分析(普通法))详解 —— matlab

目录 前言 正题 1.LDA的思想 2. 瑞利商(Rayleigh quotient)与广义瑞利商(genralized Rayleigh quotient) 3. 二类LDA原理 4.多类LDA原理 5.LDA分类 6.LDA算法流程 二类LDA matlab举例: 1.读取数据集 2.分离…

java 异步得到函数返回值_使用JavaScript进行异步编程

毫无疑问,虽然JavaScript的历史比较悠久,但这并不妨碍它成为当今最受欢迎的编程语言之一。对刚接触该语言的人来说,JavaScript的异步特性可能会有一些挑战。在本文中,我们将了解和使用Promise和async/await来编写小型异步程序。通…

Java Collection接口详解

Collection 接口是 List、Set 和 Queue 接口的父接口,通常情况下不被直接使用。Collection 接口定义了一些通用的方法,通过这些方法可以实现对集合的基本操作。定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。 Collecti…

ARMA模型的性质之MA模型

目录 一、MA模型的定义 二、MA模型的统计性质 1.常数均值 2.常数方差 3.自协方差函数q阶结尾 4.自相关系数q阶截尾 举例: 三、MA模型的可逆 1.可逆的定义和条件 2.MA与AR模型的对比 3.逆函数的递推公式 举例: 四、MA模型的偏自相关系数拖尾…

python难度如何_【经验分享】想转行学python,过来人提醒大家几点

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 提醒大家几点 一:盲目的去学 当初我在对于python这个行业什么都不了解的情况下,比如:不知道未来发展趋势,不知道学习python应该注意哪些初始问题,不知道具体的学习规划学…

ArrayList和LinkedList类的用法及区别

List 是一个有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,第一个添加到 List 集合中的元素的索引为 0&#xff…

ARMA模型的性质之ARMA模型

目录 一、ARMA模型的定义 二、平稳条件与可逆条件 三、传递形式与逆转形式 四、ARMA(p,q)模型的统计性质 1.均值 2.自协方差函数 3.自相关系数 4.ARMA(p,q)模型自相关系数拖尾,偏自相关系数拖尾 小结 一、ARMA模型的定义 具有如下结构的模型称为自回归移动…