前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java IO系列】那字节流和字符流有什么区别?

【Java IO系列】那字节流和字符流有什么区别?

原创
作者头像
思考的陈
发布2024-04-15 15:58:07
1120
发布2024-04-15 15:58:07
举报
文章被收录于专栏:JavaGetOffer系列JavaGetOffer系列

🌱以贴近现实的【面试官面试】形式涵盖大部分Java程序员需要掌握的后端知识、面试问题,系列博客收录在我开源的JavaGetOffer中,会一直完善下去,希望收到大家的 ⭐️ Star ⭐️支持,这是我创作的最大动力: https://github.com/hdgaadd/JavaGetOffer

  • 📚本期博客内容为《Java IO系列》
  • 创作不易,不妨点赞、收藏、关注支持一下
在这里插入图片描述
在这里插入图片描述

1. IO的理解

面试官:你说下对Java IO的理解?

好的面试官,Java IO有两个参与对象,一个是IO源端,一个是想要和IO源端通信的各种接收端如控制台、文件等,我们程序要保证的就是顺利的读取和顺利的写入。

2. 输入流

2.1 字节输入流读取方法

面试官:那要怎么读取字节流?

读取字节的抽象基类是InputStream,这个基类提供了3个方法可以来读取字节流。

  1. 从输入流读取下一个数据字节,值字节以0到255范围内的int返回。
代码语言:java
复制
   public abstract int read() throws IOException
  1. 从输入流读取一定数量的字节并将它们存储到缓冲区数组b中。
代码语言:java
复制
   public int read(byte b[]) throws IOException
  1. 从输入流读取最多len个字节的数据到字节数组中。
代码语言:java
复制
   public int read(byte b[], int off, int len) throws IOException

2.2 字节输入流读取实例

面试官:你说的这些不是实例,我要的是能真正读取的?

那可以用抽象基类的子类实现来读取,例如文件流FileInputStream

代码语言:java
复制
new FileInputStream(SOURCE_PATH)

我们还可以在外面加一层缓存字节流来提高读取效率。

代码语言:java
复制
new BufferedInputStream(new FileInputStream(SOURCE_PATH))

如果要把缓存流换成字符流来承接,方便使用readLine()读取某一行的话,可以使用转换流把字节输入流转换成字符输入流。

代码语言:java
复制
new BufferedReader(new InputStreamReader(new FileInputStream(SOURCE_PATH)))

2.3 缓存流提高读取效率

面试官:为什么加一层缓存流就能提高读取效率?

是这样的。因为直接使用 FileInputStream 读取文件的话,每次调用 read() 都是从磁盘读取一个字节,而每次读取都是一次系统调用。系统调用是操作系统层面的调用,涉及到用户空间和内核空间之间的上下文切换,这些切换是很昂贵的。

而如果使用缓存流,一次性从文件里读取多个字节到缓存中,可以减少系统调用同时也减少了磁盘读取,提高了读取的效率。

2.4 字节输入流末尾

面试官:读取之后呢,我怎么知道文件读取到末尾了?

例如我刚刚说到的字节流基类InputStream的3个方法,当他们返回-1,就表明输入流到达了末尾。

2.5 字符输入流

面试官:字符流读取呢?

字符流的抽象基类是Reader,同样是提供了3个方法来支持字符流读取。

  1. 读取单个字符。
代码语言:java
复制
   public int read() throws IOException
  1. 将字符读入数组。
代码语言:java
复制
   public int read(char cbuf[]) throws IOException
  1. 将字符读入数组的一部分。
代码语言:java
复制
   abstract public int read(char cbuf[], int off, int len) throws IOException

然后字符流读取的实例是FileReader,同样可以使用缓存字符流提高读取效率。

代码语言:java
复制
new BufferedReader(new FileReader(new File(SOURCE_PATH)))

3. 输出流

面试官:输出流你也讲一讲?

好的面试官。

字节输出流的抽象基类是OutputStream,字符输出流的抽象基类是Writer。他们分别提供了以下方法。

字节输出流OutputStream

  1. 将指定字节写入此输出流。
代码语言:java
复制
   public abstract void write(int b) throws IOException
  1. 将指定字节数组中的b.length字节写入此输出流。
代码语言:java
复制
   public void write(byte b[]) throws IOException 
  1. 将指定字节数组中从偏移量off开始的len个字节写入此输出流。
代码语言:java
复制
   public void write(byte b[], int off, int len) throws IOException

字符输出流Writer

  1. 写入单个字符。
代码语言:java
复制
   public void write(int c) throws IOException
  1. 写入字符数组。
代码语言:java
复制
   public void write(char cbuf[]) throws IOException
  1. 写入字符数组的一部分。
代码语言:java
复制
   abstract public void write(char cbuf[], int off, int len) throws IOException

另外字符输出流是使用字符来操作数据,所以可以用字符串来代替字符数组,JDK还支持以下入参是字符串的方法。

  1. 写入一个字符串。
代码语言:java
复制
   public void write(String str) throws IOException
  1. 写入字符串的一部分。
代码语言:java
复制
   public void write(String str, int off, int len) throws IOException

4. 字节流和字符流区别

面试官:那字节流和字符流有什么区别?

有这些不同之处,主要是3个方面。

  • 基本单位不同。字节流以字节(8位二进制数)为基本单位来处理数据,字符流以字符为单位处理数据。
  • 使用场景不同。字节流操作可以所有类型的数据,包括文本数据,和非文本数据如图片、音频等;而字符流只适用于处理文本数据。
  • 关于性能方面。因为字节流不处理字符编码,所以处理大量文本数据时可能不如字符流高效;而字符流使用到内存缓冲区处理文本数据可以优化读写操作。

5. 转换流

面试官:你刚刚提到转换流把字节输入流转换成字符输入流,可不可以倒过来?

hhh,JDK没有提供这样的方法。

是这样的,虽然字节流比字符流的使用范围更广些,但字符流比字节流操作方便,所以字符流是一个很方便的流了,没有必要把一个方便的流转换成一个不方便的流。

未完待续。。。

好了,今天的分享就先到这,我们下期《Java IO系列》继续。

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. IO的理解
  • 2. 输入流
    • 2.1 字节输入流读取方法
      • 2.2 字节输入流读取实例
        • 2.3 缓存流提高读取效率
          • 2.4 字节输入流末尾
            • 2.5 字符输入流
            • 3. 输出流
            • 4. 字节流和字符流区别
            • 5. 转换流
            • 未完待续。。。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档