Java的字节流,字符流和缓冲流对比探究

一、前言

所谓IO,也就是Input/Output。Java程序跟外部进行的数据交换就叫做Java的IO操作。程序中数据的输入输出,被抽象为流, 按照相对于程序的流向,可分为输出流和输入流。 按照数据流的格式,可分为字节流和字符流。Java IO流的体系很庞大,功能丰富。

本文主要探讨了Java中字节操作和字符操作的区别。

二、字节操作和字符操作

下图可以表示Java 的IO体系:

 :

类似于C语言中二进制文件和文本文件的区别,字符其实只是一种特殊的二进制字节,是按照一定的编码方式处理之后,按照一定规则来存储信息的数据,字符在计算机中也是由二进制组成的,只不过这种二进制可以按照一种规则解码后,成为人类可以直接阅读的自然语言,而普通的二进制文件只有计算机能直接“阅读”。字节操作和字符操作的区别就在于数据的格式。

在Java中,字节输入输出流有两个抽象基类:

  • 字节输入流:InputStream
  • 字节输出流:OutputStream

字符输入输出流也有两个抽象基类:

  • 字符输入流:Reader

  • 字符输出流:Writer

此外, Java提供了从字节流到字符流的转换流,分别是InputStreamReader和OutputStreamWriter,但没有从字符流到字节流的转换流。实际上:

字符流=字节流+编码表

一次读取一个字节数组的效率明显比一次读取一个字节的效率高,因此Java提供了带缓冲区的字节类,称为字节缓冲区类:BufferedInputStream和BufferedOutputStream,同理还有字符缓冲区类BufferedReader和BufferedWriter。

在使用场景上,无法直接获取文本信息的二进制文件,比如图片,mp3,视频文件等,只能使用字节流。而对于文本信息,则更适合使用字符流。

三、两种方式的效率测试

下面通过编写测试程序来比较两种方式的效率区别:

3.1 测试代码

笔者编写了8个方法来分别测试字节方式/字符方式的输入输出流,带缓冲区的输入输出流。

package com.verygood.island;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.platform.commons.annotation.Testable;

import java.io.*;

/**
 * @author <a href="mailto:kobe524348@gmail.com">黄钰朝</a>
 * @description
 * @date 2020-05-27 08:50
 */
@Testable
public class UnitTest {
   

    public static final String PATH = "C:\\Users\\Misterchaos\\Documents\\Java Develop Workplaces\\" +
            "Github repository\\island\\src\\test\\java\\com\\verygood\\island\\";

    /**
     * 用于输出的对象
     */
    public static byte[] outputbytes = null;

    public static char[] outputchars = null;

    int count = 1;

    /**
     * 用于输入的对象
     */
    public static final File inputFile = new File("C:\\Users\\Misterchaos\\Downloads\\安装包\\TEST.zip");


    @BeforeClass
    public static void before() {
   
        StringBuilder stringBuilder = new StringBuilder("");
        for (int i = 0; i < 1000000; i++) {
   
            stringBuilder.append("stringstringstringstringstringstring");
        }
        outputbytes = stringBuilder.toString().getBytes();
        outputchars = stringBuilder.toString().toCharArray();
    }


    @Test
    public void test0() {
   
        System.out.println("--------------------------------------------------------");
        System.out.println("                      测试输出流                          ");
        System.out.println("--------------------------------------------------------");
    }


    // 字节流
    @Test
    public void test1() {
   
        try {
   
            System.out.println("********方式一:字节流输出**********");
            // 新建文件命名
            String name = PATH + "字节流输出文件.txt";
            File file = new File(name);
            // 创建输入输出流对象
            FileOutputStream fos = new FileOutputStream(file);
            // 读写数据
            long s1 = System.currentTimeMillis();// 测试开始,计时
            writeBytes(fos);
            long s2 = System.currentTimeMillis();// 测试结束,计时
            fos.close();
            System.out.println("输出文件耗时:" + (s2 - s1) + "ms");
            System.out.println("文件大小:" + file.length() / 1024 + "KB");
            file.delete();
        } catch (FileNotFoundException e) {
   
            e.printStackTrace();
        } catch (IOException e
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值