详解IO流

IO概述

1.什么是IO

I/O是Input/Out普通的缩写,I/O技术是非常使用的技术,用于处理设备之间的数据传输。

在Java程序中,对于数据的输入/输出操作以“流(stream)”的方式及逆行,java.io包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据

刚刚我们谈到了流,那什么是流呢?

2.流及流的分类

2.1什么是流?

流(stream),是一个抽象的概念,是指一连串的数据(字符或子节),是以先进先出的方式发送信息的渠道。

当程序需要读取数据时,就会开启一个通向数据源的流,数据在传输过程中像“流动”一样,通常流的特点有以下三个方面:

  • 先进先出:最先写入输出流的数据最先被输入流读取到
  • 顺序存取:可以一个接一个地往流中写以一串子节,读出时也将按写入顺序读取一串子节
  • 只读或只写:每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流。

2.2流的分类

通常流按照不同的分类标准可以分为以下三种:

  • 按操作数据单位不同分为:字节流(8bit)和字符流(16bit)
    通常对于文本文件我们会使用字符流,对于非文本文件使用子节流
  • 按数据流的流向不同分为:输入流和输出流
  • 按数据流不同角色分为:节点流和处理流
    这里对于节点流和处理流现有一个初步的认知,我们假如把数据的输出端比作水龙头,把数据的输入端比作用户,那么字节流相当于原生管道,处理流相当于为了加快水流速建立在原生管道上的加速管道
    在这里插入图片描述
    将下来我们用一张图来描绘以下三种分类的形象表示
    在这里插入图片描述

3.IO流对象

在这里插入图片描述
整个IO流共涉及四十多个类,但是都是有规律可循的,都是由四大抽象基类派生而来

抽象基类 字节流 字符流
输出流 OutputStream Writer
输入流 InputStream Reader

3.1字节流

由上图可得字节流中InputStreamOutputStream是两个抽象类,是整个字节流的基类,剩下的所有字节流实现类都拓展于这两个类,对于字节流,处理流等都是继承于这两个父类,常见的字节流有:

  • FIleInputStream:输入字节流,用于读取视频,音频,图片等非文本文件
  • FileOutputStream:输出字节流,用于写出非文本文件
  • BufferedInputStream:输入处理流,作为FileInputStream的处理流,加快访问效率,以字节流为参数构建
  • BufferedOutputStream:输出处理流,作为FileOutputStream的处理流,加快访问效率,以字节流为参数构建

3.2字符流

对于字符流ReaderWriter作为抽象基类,是字符流的基类,剩下的字符流都拓展于这两个类,常见的字符流有:

  • FileReader:输入字符流,用于读取txt等文本文件
  • FileWriter:输出字符流,用于写出txt等文本文件
  • BufferedReader:输入处理流,作为FileReader的处理流,加快访问效率,以字节流为参数构建
  • BufferedWriter:输出处理流,作为FileWriter的处理流,加快访问效率,以字节流为参数构建

3.3字节流和字符流和相互转换

这里要使用的转换流,转换流也是一种处理流,且属于字符流的一种

  • InputStreamReader:用于将字节流转换成字符流,在创建转换流时,要指定字符集的转换规则,默认使用编译器指定的字符集,我们根据文本的保存方式,在创建时指名字符集
InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
  • OutputStreamReader:用于将字符流转换成字节流,创建时同上,指名字符集

4.IO流方法

4.1字符流方法

输入流方法:

  • read():Reads a single character,The character read, or -1 if the end of the stream has been reached,每次读一个字符,直到流结束时返回-1
  • read(char[] cubf):Reads characters into a portion of an array.,从此输入流中将最多 b.length 个字符的数据读入一个 byte 数组中。
  • read(char[] cubf,int off,int length):Reads characters into a portion of an array.,每一次将字符读到一个数组中,off表示偏移量(从那个字符开始读),length表示读取的最大字符数
    关于使用cubf数组中的一些小细节
    如图所以,假如我们的cubf数组大小设置为5,每一次装装载并不是清空,而且从前至后依次覆盖在这里插入图片描述
  • 对于字符处理流:readLine(),每次读入一行,当流结束时返回null
    输出流方法:
  • write(int c):向此文件输出流写入一个字符
  • write(char cbuf[], int off, int len) :写入字符数组的某个部分
  • write(String str, int off, int len) :写入字符串的某个部分
  • write(String str):写入字符串
  • write(char cbuf[]) :写入字符数组
  • 对于字符处理流:newLine(),每次读一行,自动换行

4.2字节流方法

基本同上,只是写入的数据由字符变为字节

5.各种字符集详解

首先我们要明白两个概念,什么是字节(Byte),一字节由8个二进制位组成,也就是1byte=8bit,可以表示0-255共256个数。

字符与字节:

  • ASCII码:一个英文字母(不分大小写)占一个字节的空间,一个中文汉字占两个字节的空间。一个二进制数字序列,在计算机中作为一个数字单元,一般为8位二进制数,换算为十进制。最小值-128,最大值127。如一个ASCII码就是一个字节。

  • UTF-8编码:一个英文字符等于一个字节,一个中文(含繁体)等于三个字节。中文标点占三个字节,英文标点占一个字节

  • Unicode编码:一个英文等于两个字节,一个中文(含繁体)等于两个字节。中文标点占两个字节,英文标点占两个字节

6.代码实例

6.1使用FileReaderFileWriter实现文本的复制

这里我们要注意的是异常处理,假如我们在执行read方法时,抛出了io的异常,此时程序不在向下执行,但是我们的流已经创建好了,JVM的回收算法对于流是无能为力的,所以不会执行close操作会造成资源浪费,我们将close操作放在finally中进行关闭

public class TestFileReader {
   
    public static void main(String[] args) {
   
        FileReader fr = null;
        FileWriter fw = null;
        try {
   
            // 1.创建File类,指名操作对象
            File resFile = new File("src\\hello.txt");
            File desFile = new File("src\\hello1.txt");
            // 2.创建流对象
            fr = new FileReader
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值