Java IO流详解(三)——字节流InputStream和OutPutStream

时间:2022-09-09 15:19:44

我们都知道在计算机中,无论是文本、图片、音频还是视频,所有的文件都是以二进制(字节)形式存在的,IO流中针对字节的输入输出提供了一系列的流,统称为字节流。字节流是程序中最常用的流。在JDK中,提供了两个抽象类InputStream和OutputStream,它们是字节流的*父类,所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。既然二者是抽象类,那么就不能实例化,都是依赖于具体继承它们的子类去实现。但二者抽象类中也包含它们各自的方法,如果我们先了解清楚抽象类中每一个方法的含义,那么对于后续具体的子类将会有非常大的帮助。

1、字节输入流InputStream

InputStream是所有字节输入流的父类,定义了所有字节输入流都具有的共同特征。其内部提供的方法如下:

Java IO流详解(三)——字节流InputStream和OutPutStream

上图中重载的三个read()方法都是用来读数据的。

  • int read():每次读取一个字节,返回读取到的字节。
  • int read(byte[] b):每次读取 b 数组长度的字节数,然后返回读取的字节,读到末尾时返回-1。
  • int read(byte[] b,int off,int len):每次读取 b 数组长度的字节数,从数组b 的索引为off 的位置开始,长度为len个字节。

其中InputStream的子类FileInputStream是专门用于读取文件中的数据,通过它将目标设备上的数据读入到程序。

FileInputStream读入文件举例(读取的hello.txt文件内容是 ABCDEFGH):

package com.thr;

import java.io.*;

/**
* @author Administrator
* @date 2020-02-21
* @desc 字节输入流FileInputStream
*/
public class FileInputStreamTest { public static void main(String[] args) {
//定义输入流
FileInputStream fis =null;
try {
//1、创建文件对象
File file = new File("D:\\IO\\hello.txt");
//2、创建输入流对象
fis = new FileInputStream(file);
//用定义字节数组,作为装字节数据的容器
byte[] buffer =new byte[5];
int len;//记录每次读取的字节个数
System.out.println(fis.read(buffer));
while ((len=fis.read(buffer))!=-1){
//转成String型,否则输出ASCII码
String str=new String(buffer,0,len);
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
} }
}
运行结果:
ABCDE
FGH

如果我们在读取的hello.txt文件中添加几个中文字,再次用同样的代码来运行看一下会发生什么情况(hello.txt内容 ABCDEFGH中国人):

运行结果的截图:

Java IO流详解(三)——字节流InputStream和OutPutStream

可以发现运行的结果出现了乱码,这是因为每次读取五个字符,而一个utf-8的中文则占了3个字节,而第二次读取的时候【中】这个字的字节数并没有读完,而【国】字全部读完了,所以【中】和【人】字都出现了乱码而【国】没有出现乱码。这里画个图好理解一点。

Java IO流详解(三)——字节流InputStream和OutPutStream

为了避免可能出现的乱码,要么把 byte[] 数组容量增大,要么就使用字符输入输出流来处理(对于纯文本最好使用字符流)。

2、字节输出流OutputStream

OutputStream是所有字节输出流的父类,定义了所有字节输出流都具有的共同特征。其内部提供的方法如下:

Java IO流详解(三)——字节流InputStream和OutPutStream

上图中重载的三个write()方法都是用来写数据的。

  • void write(int b):把一个字节写入到文件中。
  • void write(byte[] b):把数组b 中的所有字节写入到文件中。
  • void write(byte[] b,int off,int len):把数组b 中的字节从 off 索引开始的 len 个字节写入到文件中。

其中OutputStream的子类FileOutputStream是门用于读出文件中的数据,通过它将数据从程序输出到目标设备。

FileOutputStream输出文件举例:

package com.thr;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; /**
* @author Administrator
* @date 2020-02-21
* @desc 字节输出流FileOutputStream
*/
public class FileOutputStreamTest { public static void main (String[] args) {
//定义字节输出流
FileOutputStream fos =null;
try { //1、创建文件对象
File file = new File("D:\\IO\\hello.txt");
//2、创建输出流对象
fos = new FileOutputStream(file); fos.write(97);
//后面的 \r\n表示回车换行
fos.write("中国人!\r\n".getBytes());
//从索引2开始输出4个字节
fos.write("ABCDEFGH".getBytes(),2,4); } catch (IOException e) {
e.printStackTrace();
} finally {
//释放资源
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

运行后结果是: a中国人!CDEF 。而如果我们多次运行测试代码会发现,每次运行完程序之后文件大小并没有改变,说明每次运行都创建了一次新的输出流对象,每次都清空目标文件中的数据。那么要如何才能保留目标文件中数据,还能继续追加新数据呢?其实很简单,如下两个FileOutputStream构造方法:

public FileOutputStream(File file, boolean append)

public FileOutputStream(String name, boolean append)

这两个构造方法,第二个参数中都需要传入一个boolean类型的值,true表示追加数据,false表示不追加也就是清空原有数据。

3、字节流拷贝文件

在应用程序中,IO流通常都是成对出现的,即输入流和输出流一起使用。而文件的拷贝就需要通过输入流来读取文件中的数据,通过输出流将数据写入文件。

package com.thr;

import java.io.*;

/**
* @author Administrator
* @date 2020-02-21
* @desc 将文件从D盘拷贝到C盘
*/
public class FileInputOutputStreamTest {
public static void main(String[] args) { //定义输入流
FileInputStream fis =null;
//定义输出流
FileOutputStream fos=null; //idea的try-catch快捷键Ctrl+Alt+T
try {
//创建文件对象
File f1 = new File("D:\\IO\\1.jpg");
File f2 = new File("C:\\2.jpg");
//创建输入输出流对象
fis = new FileInputStream(f1);
fos = new FileOutputStream(f2);
//读取
byte [] bytes = new byte[1024];
int len;
//读出
while((len=fis.read(bytes))!=-1){
fos.write(bytes, 0, len);
}
System.out.println("拷贝成功...");
} catch (IOException e) {
e.printStackTrace();
} finally {
//释放
try {
fis.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Java IO流详解(三)——字节流InputStream和OutPutStream的更多相关文章

  1. Java io流详解三

    public class IOpractise { public void iotest() { int b= 0; FileInputStream fis = null; try { fis = n ...

  2. java IO流详解

    流的概念和作用 学习Java IO,不得不提到的就是JavaIO流. 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  3. 《Java基础知识》Java IO流详解

    Java IO概念 1. 用于设备之间的数据传输. 2. Java 将操作数据流的功能封装到了IO包中. 3. 数据流流向分:输入流和输出流,操作对象为文件. 4. 流按照操作数据分:字节流(通用)和 ...

  4. Java IO流详解(六)——转换流

    转换流也是一种处理流,它提供了字节流和字符流之间的转换.在Java IO流中提供了两个转换流:InputStreamReader 和 OutputStreamWriter,这两个类都属于字符流.其中I ...

  5. Java IO流详解(一)——简单介绍

    文件在程序中是以流的形式来传输的.所以用Java来传输文件就得使用到Java IO流. 1.流的概念和作用 流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象<Thinkin ...

  6. Java IO流详解(五)——缓冲流

    缓冲流也叫高效流,是处理流的一种,即是作用在流上的流.其目的就是加快读取和写入数据的速度. 缓冲流本身并没有IO功能,只是在别的流上加上缓冲效果从而提高了效率.当对文件或其他目标频繁读写或操作效率低, ...

  7. Java IO流详解(二)——File类

    在上一章博客中简单的介绍了Java IO流的一些特征.也就是对文件的输入输出,既然至始至终都离不开文件,所以Java IO流的使用得从File这个类讲起. File类的描述:File类是文件和目录路径 ...

  8. Java io流详解四

    转载地址:http://www.cnblogs.com/rollenholt/archive/2011/09/11/2173787.html 写在前面:本文章基本覆盖了java IO的全部内容,jav ...

  9. Java io流详解二

    原文地址https://www.cnblogs.com/xll1025/p/6418766.html 一.IO流概述 概述: IO流简单来说就是Input和Output流,IO流主要是用来处理设备之间 ...

随机推荐

  1. RCP&colon; MANIFEST&period;MF&comma; plugin&period;xml&comma; build&period;properties三种文件的区别

    在Eclipse插件开发中, MANIFEST.MF, plugin.xml, build.properties是三种最常见的文件,由于它们共享同一个编辑器(Plug-in Manifest Edit ...

  2. javascript&lowbar;basic&lowbar;03之函数、循环、数组

    1.函数:函数(Function),方法(Method),过程(Procedure): 2.默认为假的情况: ①if(0){}:②if(0.0){}:③if(null){}:④if("&qu ...

  3. Canvas修行之黑客帝国代码雨

    既然是修行,不卖弄关子,不吊胃口,修行成果必须先晒一晒. 下图是我用canvas画的黑客帝国代码雨,想起当年看黑客帝国时,那个代码雨场景让我心旷神怡,大开脑洞,满脑子是那种三维空间,无数0和1像雨一样 ...

  4. linux 多网卡 跃点数

    centos6.4 配置两块网卡,eth0设置静态IP,8网段,eth1无线配置dhcp,都是开机启动. 但是eth1无线网卡一旦连接至开放网络(需要web登陆),就替换了之前eth0配置的默认网关, ...

  5. Cocos2D-x权威指南&colon;通过节点控制屏幕中的全体渲染对象

    本节,已经能够利用我们眼下所学的知识做出一些有趣的东西.之前已经说过,CCNode类没有贴图,也就是说在屏幕上单独建立一个节点是没有不论什么效果的,可是能够通过这个"无形"的节点来 ...

  6. iOS开发--混编篇&amp&semi;swift与OC混合使用

    Swift与OC混合使用 swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编. ...

  7. C&num; - InnerList

    运行效果: 代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; name ...

  8. ubuntu下命令使用

    sudo apt-get -f install:修复函数依赖 df -hl:查看空间使用状况 nvidia-smi:常看GPU使用率

  9. C&plus;&plus;自己实现一个String类

    C++自己实现一个String类(构造函数.拷贝构造函数.析构函数和字符串赋值函数) #include <iostream> #include <cstring> using ...

  10. ComputeShader中Counter类型的使用

    接上一篇:https://www.cnblogs.com/hont/p/10122129.html 除了Append类型对应的Consume/AppendStructuredBuffer还有一个Cou ...