热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解JAVA字节流和字符流

这篇文章主要介绍了JAVA字节流和字符流的的相关资料,文中讲解非常的细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

1、InputStream 和 Reader

InputStream 和 Reader 是所有输入流的抽象基类,本身并不能创建实例来执行输入,但它们将成为所有输入流的模板,所以它们的方法是所有输入流都可使用的方法。

在 InputStream 里包含如下三个方法。

  • int read():从输入流中读取单个字节,返回所读取的字节数据(字节数据可直接转换为int类型)。
  • int read(byte[] b):从输入流中最多读取 b.length 个字节的数据,并将其存储在字节数组 b 中,返回实际读取的字节数。
  • int read(byte[] b, int off, int len):从输入流中最多读取 len 个字节的数据,并将其存储在数组 b 中,放入数组 b 中时,并不是从数组起点开始,而是从 off 位置开始,返回实际读取的字节数。

在 Reader 里包含如下三个方法。

  • int read():从输入流中读取单个字符,返回所读取的字符数据(字符数据可直接转换为int类型)。
  • int read(char[] cbuf):从输入流中最多读取 cbuf.length 个字符的数据,并将其存储在字符数组 cbuf 中,返回实际读取的字符数。
  • int read(char[] chuf, int off, int len):从输入流中最多读取 len 个字符的数据,并将其存储在字符数组 cbuf 中,放入数组 cbuf 中时,并不是从数组起点开始,而是从 off 位置开始,返回实际读取的字符数。

对比 InputStream 和 Reader 所提供的方法,就不难发现这两个基类的功能基本是一样的。

正如前面提到的,InputStream 和 Reader 都是抽象类,本身不能创建实例,但它们分别有一个用于读取文件的输入流:FileInputStream 和 FileReader,它们都是节点流一一会直接和指定文件关联。

下面程序示范了使用 FileInputStream 来读取自身的效果。

public class FileInputStreamTest {
  public static void main(String[] args) throws IOException {
    // 创建字节输入流
    FileInputStream fis = new FileInputStream("F:\\eclipse-workspace\\demo\\src\\com\\jwen\\demo15_3\\FileInputStreamTest.java");
    // 创建一个长度为1024的“竹筒”
    byte[] bbuf = new byte[1024];
    // 用于保存实际读取的字节数
    int hasRead = 0;
    // 使用循环来重复“取水”过程
    while ((hasRead = fis.read(bbuf)) > 0) {
      // 取出“竹筒”中水滴(字节),将字节数组转换成字符串输入!
      System.out.print(new String(bbuf, 0, hasRead));
    }
    // 关闭文件输入流,放在finally块里更安全
    fis.close();
  }
}

上面程序中的粗体字代码是使用 FileInputStream 循环“取水”的过程,运行上面程序,将会输出上面程序的源代码。

注意:上面程序创建了一个长度为1024的字节数组来读取该文件,实际上该Java源文件的长度还不到1024字节,也就是说,程序只需要执行一次 read() 方法即可读取全部内容。但如果创建较小长度的字节数组,程序运行时在输出中文注释时就可能出现乱码一一这是因为本文件保存时采用的是 GBK 编码方式,在这种方式下,每个中文字符占2字节,如果 read() 方法读取时只读到了半个中文字符,这将导致乱码。

上面程序最后使用了 fis.close() 来关闭该文件输入流,与 JDBC 编程一样,程序里打开的文件 IO 资源不属于内存里的资源,垃圾回收机制无法回收该资源,所以应该显式关闭文件资源。Java 7 改写了所有的 IO 资源类,它们都实现了 AutoCloseable 接口,因此都可通过自动关闭资源的 try 语句来关闭这些 IO 流。下面程序使用 FileReader 来读取文件本身。

public class FileReaderTest {
  public static void main(String[] args) {
    try (
      // 创建字符输入流
      FileReader fr = new FileReader("F:\\eclipse-workspace\\demo\\src\\com\\jwen\\demo15_3\\FileReaderTest.java")) {
      // 创建一个长度为32的“竹筒”
      char[] cbuf = new char[32];
      // 用于保存实际读取的字符数
      int hasRead = 0;
      // 使用循环来重复“取水”过程
      while ((hasRead = fr.read(cbuf)) > 0) {
        // 取出“竹筒”中水滴(字符),将字符数组转换成字符串输入!
        System.out.print(new String(cbuf, 0, hasRead));
      }
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}

上面的 FileReaderTest.java 程序与前面的 FileInputStreamTest.java 并没有太大的不同,程序只是将字符数组的长度改为32,这意味着程序需要多次调用 read() 方法才可以完全读取输入流的全部数据。程序最后使用了自动关闭资源的 try 语句来关闭文件输入流,这样可以保证输入流一定会被关闭。

除此之外,InputStream 和 Reader 还支持如下几个方法来移动记录指针。

  • void mark(int readAheadLimit):在记录指针当前位置记录一个标记(mark).
  • boolean markSupported():判断此输入流是否支持 mark() 操作,即是否支持记录标记。
  • void reset():将此流的记录指针重新定位到上一次记录标记(mark)的位置。
  • long skip(long n):记录指针向前移动个字节/字符。

2、OutputStream 和 Writer

OutputStream 和 Writer 也非常相似,两个流都提供了如下三个方法。

  • void write(int c):将指定的字节/字符输出到输出流中,其中 c 既可以代表字节,也可以代表字符。
  • void write(byte[]/char[] buf):将字节数组/字符数组中的数据输出到指定输出流中。
  • void write(byte[]/char[] buf, int off, int len):将字节数组/字符数组中从 off 位置开始,长度为 len 的字节/字符输出到输出流中。

因为字符流直接以字符作为操作单位,所以 Writer 可以用字符串来代替字符数组,即以 String 对象作为参数。Writer 里还包含如下两个方法。

  • void write(String str):将字符串里包含的字符输出到指定输出流中。
  • void write(String str, int off, int len):将字符串里从 off 位置开始,长度为 len 的字符输出到指定输出流中。

下面程序使用 FileInputStream 来执行输入,并使用 FileOutputStream 来执行输出,用以实现复制 FileOutputStreamTest.java 文件的功能。

public class FileOutputStreamTest {
  public static void main(String[] args) {
    try (
      // 创建字节输入流
      FileInputStream fis = new FileInputStream("FileOutputStreamTest.java");
      // 创建字节输出流
      FileOutputStream fos = new FileOutputStream("newFile.txt")) {
      byte[] bbuf = new byte[32];
      int hasRead = 0;
      // 循环从输入流中取出数据
      while ((hasRead = fis.read(bbuf)) > 0) {
        // 每读取一次,即写入文件输出流,读了多少,就写多少。
        fos.write(bbuf, 0, hasRead);
      }
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

运行上面程序,将看到系统当前路径下多了一个文件:newFile.txt,该文件的内容和 FileOutputStreamTest.java 文件的内容完全相同。

注意:使用 Java 的 IO 流执行输出时,不要忘记关闭输出流,关闭输出流除可以保证流的物理资源被回收之外,可能还可以将输出流缓冲区中的数据 flush 到物理节点里(因为在执行 close() 方法之前,自动执行输出流的 flush() 方法)。Java 的很多输出流默认都提供了缓冲功能,其实没有必要刻意去记忆哪些流有缓冲功能、哪些流没有,只要正常关闭所有的输出流即可保证程序正常。

如果希望直接输出字符串内容,则使用 Writer 会有更好的效果,如下程序所示。

public class FileWriterTest {
  public static void main(String[] args) {
    try (FileWriter fw = new FileWriter("poem.txt")) {
      fw.write("锦瑟 - 李商隐\r\n");
      fw.write("锦瑟无端五十弦,一弦一柱思华年。\r\n");
      fw.write("庄生晓梦迷蝴蝶,望帝春心托杜鹃。\r\n");
      fw.write("沧海月明珠有泪,蓝田日暖玉生烟。\r\n");
      fw.write("此情可待成追忆,只是当时已惘然。\r\n");
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
}

运行上面程序,将会在当前目录下输出一个 poem.txt 文件,文件内容就是程序中输出的内容。

注意:上面程序在输出字符串内容时,字符串内容的最后是\r\n,这是 Windows 平台的换行符,通过这种方式就可以让输出内容换行;如果是 UNIX/Linux/BSD 等平台,则使用 \n 就作为换行符。

以上就是详解JAVA 字节流和字符流的详细内容,更多关于JAVA 字节流和字符流的资料请关注其它相关文章!


推荐阅读
  • 阿里云ecs怎么配置php环境,阿里云ecs配置选择 ... [详细]
  • 本文详细介绍如何在Linux系统中配置SSH密钥对,以实现从一台主机到另一台主机的无密码登录。内容涵盖密钥对生成、公钥分发及权限设置等关键步骤。 ... [详细]
  • Python第三方库安装的多种途径及注意事项
    本文详细介绍了Python第三方库的几种常见安装方法,包括使用pip命令、集成开发环境(如Anaconda)以及手动文件安装,并提供了每种方法的具体操作步骤和适用场景。 ... [详细]
  • 磁盘健康检查与维护
    在计算机系统运行过程中,硬件或电源故障可能会导致文件系统出现异常。为确保数据完整性和系统稳定性,定期进行磁盘健康检查至关重要。本文将详细介绍如何使用fsck和badblocks工具来检测和修复文件系统及硬盘扇区的潜在问题。 ... [详细]
  • 在创建新的Android项目时,您可能会遇到aapt错误,提示无法打开libstdc++.so.6共享对象文件。本文将探讨该问题的原因及解决方案。 ... [详细]
  • 本文作者分享了在阿里巴巴获得实习offer的经历,包括五轮面试的详细内容和经验总结。其中四轮为技术面试,一轮为HR面试,涵盖了大量的Java技术和项目实践经验。 ... [详细]
  • 深入理解Lucene搜索机制
    本文旨在帮助读者全面掌握Lucene搜索的编写步骤、核心API及其应用。通过详细解析Lucene的基本查询和查询解析器的使用方法,结合架构图和代码示例,带领读者深入了解Lucene搜索的工作流程。 ... [详细]
  • 雨林木风 GHOST XP SP3 经典珍藏版 V2017.11
    雨林木风 GHOST XP SP3 经典珍藏版 V2017.11 ... [详细]
  • 本文详细介绍了Linux系统中软链接和硬链接的概念、创建方法及其应用场景。通过实例解释了两者的区别,包括如何防止误删文件及软链接在跨文件系统时的优势。 ... [详细]
  • 目录一、salt-job管理#job存放数据目录#缓存时间设置#Others二、returns模块配置job数据入库#配置returns返回值信息#mysql安全设置#创建模块相关 ... [详细]
  • 本文详细介绍了如何在预装Ubuntu系统的笔记本电脑上安装Windows 7。针对没有光驱的情况,提供了通过USB安装的具体方法,并解决了分区、驱动器无法识别等问题。 ... [详细]
  • 嵌入式开发环境搭建与文件传输指南
    本文详细介绍了如何为嵌入式应用开发搭建必要的软硬件环境,并提供了通过串口和网线两种方式将文件传输到开发板的具体步骤。适合Linux开发初学者参考。 ... [详细]
  • 本文详细介绍了在不同操作系统中查找和设置网卡的方法,涵盖了Windows系统的具体步骤,并提供了关于网卡位置、无线网络设置及常见问题的解答。 ... [详细]
  • 如何使用Ping命令来测试网络连接?当网卡安装和有关参数配置完成后,可以使用ping命令来测试一下网络是否连接成功。以winXP为例1、打开XP下DOS窗口具体操作是点击“开始”菜 ... [详细]
  • 本文探讨了如何解决PHP文件无法写入本地文件的问题,并解释了PHP文件中HTML代码无效的原因,提供了一系列实用的解决方案和最佳实践。 ... [详细]
author-avatar
欣欣2602916441
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有