字符流和字节缓冲流

本文详细介绍了Java中的IO流分类,重点讲解了字符流和字节缓冲流的概念及应用。字符流在处理文本文件时能更好地避免乱码问题,而缓冲流通过内部缓冲区提高读写效率。文章还提供了字节缓冲流复制文件的代码示例,对比了不同方法的效率差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IO流的分类

  • 根据流的流向分类:
    • 输入流:将数据从 其他设备 上读取到 内存 中的流。以 InputStream 、Reader 结尾。
    • 输出流:将数据从 内存 中写出到 其他设备 上的流。以 OutputStream 和 Writer 结尾。
  • 根据数据的类型分类:
    • 字节流:以字节为单位,读写数据的流。以 InputStream 和 OutputStream 结尾。
    • 字符流:以字符为单位,读写数据的流。以 Reader 和 Writer 结尾。
  • 根据 IO 流的角色不同分类:
    • 节点流:可以从或向一个特定的地方(节点)读取数据。如 FileReader 。
    • 处理流:对一个已经存在的流进行连接和封装,通过锁封装的流的功能实现数据读写。如:BufferReader ,处理流的构造方法总是要带一个其它的流对象做参数。一个流对象经过多次其它流的多次包装,称为流的链接。
  • 常用的节点流:
    • 文件:FileInputStream 、FileOutputStream 、FileReader 、FileWriter 文件进行处理的节点流。
    • 字符串:StringReader 、StringWriter 对字符串进行处理的节点流。
    • 数组: ByteArrayInputStream 、ByteArrayOutputStream、CharArrayReader 、CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
    • 管道:PipedInputStream 、PipedOutputStream 、PipedReader 、PipedWriter 对管道进行处理的节点流。
  • 常用处理流:
    • 缓冲流:BufferedInputStream 、BufferedOutputStream 、BufferedReader 、BufferedWriter ---增加缓冲功能,避免频繁读写硬盘。
    • 转换流:InputStreamReader 、OutputStreamReader --- 实现字节流和字符流之间的转换。
    • 数据流:DataInputStream 、DataOutputStream - 提供读写 Java 基础数据类型功能。
    • 对象流:ObjectInputStream 、ObjectOutputStream -- 提供直接读写 Java 对象功能。

输入流

输出流

字节流

字节输入流 InputStream

字节输出流 OutputStream

字符流

字符输入流 Reader

字符输出流 Writer

字符流 

  •        如果利用字节流,把文本文件的中文,读取到内存中,有可能还会出现乱码
    • 如果利用字节流,把中文写到文本文件中,也有可能出现乱码

字符流概述

由于字节流操作中文不是特别的方便,所以Java就提供字符流

字符流 = 字节流 + 编码表

 代码演示:

import java.io.FileReader;
import java.io.FileWriter;
    /*
    *   flush()刷新和close()关闭方法的差别
    *           close()方法中包含flush()方法
    *
    *       FileOutputStream(字节流)
    *               字节流也是有缓冲区的,不过很小,可以忽略不计
    *       FileWriter(字符流)
    *               该类的构造函数假定默认字符编码和默认字节缓冲区大小是可以接受的
    *
    *       在使用字符流写数据的时候,并不是直接写到文件中的,而是先保存到缓冲区,如果需要再写入到文件中(需要手动的刷新流和关闭流对象)
    *
    * */
public class FileWrite {
    public static void main(String[] args) throws Exception {
        //写数据
        FileWriter fw = new FileWriter("aaa.txt");
        String str = "恭喜发财";
        fw.write(str);
        fw.close();
        //读数据
        FileReader fr = new FileReader("aaa.txt");
        //由于此处read为int类型,所以转换是ASCLL码;(可以用char转换为字符)
        int read;
        /*while ((read=fr.read())!=-1){
            System.out.println("read = " + (char)read);
        }*/
        //也可以使用char[]数组进行存储后输出
        char[] chars = new char[1024];
        while ((read=fr.read(chars))!=-1){
            System.out.println(new String(chars,0,read));
        }
        fr.close();

    }
}

字节缓冲流

2.6.1 缓冲流概述

  • 缓冲流,也叫高效流,按照数据类型分类:
    • 字节缓冲流:BufferedOutputStream 、BufferedInputStream 。
    • 字符缓冲流:BufferedReader 、BufferedWriter 。
  • 缓冲流会在内部创建一个缓冲区数组,缺省使用 8192 个字节(8kb)的缓冲区。
  • 缓冲流仅仅提供缓冲区,而真正的读写数据还得依靠基本的字节流、字符流对象进行操作

由于字符与字节差不多,所以这里只写一个字节的缓冲流了 

字节缓冲流

字节缓冲流介绍

  • lBufferOutputStream:该类实现缓冲输出流.通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
  • lBufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组.当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节

构造方法:

方法名

说明

BufferedOutputStream(OutputStream out)

创建字节缓冲输出流对象

BufferedInputStream(InputStream in)

创建字节缓冲输入流对象

代码演示:

import java.io.*;

public class Buffered {
    public static void main(String[] args) throws Exception {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("aaa.txt"));
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aaa.txt"));
        //写数据
        String str = "红包拿来";
        bos.write(str.getBytes());
        //释放资源
        bos.close();
        //读数据
        int read;
        byte[] bytes = new byte[1024];
        while ((read=bis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,read));
        }
        //释放资源
        bis.close();
    }
}

 

字节缓冲流复制文件

  • 案例需求
    把“aaa.txt”复制到模块目录下的“abc.txt”
  • 实现步骤
    • 根据数据源创建字节输入流对象
    • 根据目的地创建字节输出流对象
    • 读写文本,复制数据
    • 释放资源

这里我写了三种效率不同的方法,可以自己手动运行看下差别

代码演示:

import java.io.*;

public class BuffereInputStream {
    public static void main(String[] args) throws Exception {
        //user();
        //vip_user();
        //Svip_user();
    }

    public static void user() throws Exception {
        long start = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("aaa.txt");
        FileOutputStream fos = new FileOutputStream("abc.txt");
        int read;
        while ((read=fis.read())!=-1){
            fos.write(read);
        }
        long end = System.currentTimeMillis();
        System.out.println(" 耗时: " + (end - start));
        //释放资源
        fos.close();
        fis.close();
    }

    public static void vip_user() throws Exception {
        long start = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("aaa.txt");
        FileOutputStream fos = new FileOutputStream("abc.txt");
        int read;
        byte[] bytes = new byte[1024];
        while ((read=fis.read(bytes))!=-1){
            fos.write(bytes,0,read);
        }
        long end = System.currentTimeMillis();
        System.out.println(" 耗时: " + (end - start));
        //释放资源
        fos.close();
        fis.close();
    }

    public static void Svip_user() throws Exception {
        long start = System.currentTimeMillis();
        FileInputStream fis = new FileInputStream("aaa.txt");
        BufferedInputStream bis = new BufferedInputStream(fis);
        FileOutputStream fos = new FileOutputStream("abc.txt");
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        int read;
        byte[] bytes = new byte[1024];
        while ((read=bis.read(bytes))!=-1){

            bos.write(bytes,0,read);
        }
        long end = System.currentTimeMillis();
        //释放资源
        bos.close();
        fos.close();
        bis.close();
        fis.close();
        System.out.println(" 耗时: " + (end - start));
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值