《Java黑皮书基础篇第10版》 第17章【笔记】

第十七章 二进制I/O

17.1 引言

文件可以不严谨的分类为文本文件和二进制文件。文本文件指的是可以用文件编辑器进行查看和修改的,二进制文件则不可以使用文本编辑器查看和修改。

例如,Test.java文件储存在文本文件中,因此可以用文本编辑器读取,但是Test.class则是二进制文件,由java虚拟机读取

Java提供了许多实现文件输入/输出的类。这些类可以分为文本I/O类和二进制I/O类。在12.11节中我们已经介绍过文本I/O类,因此本章开始介绍二进制I/O的类

17.2 在Java中如何处理文本I/O

使用Scanner类读取文本数据,使用PrintWriter类写入文本数据

17.3 文本I/O与二进制I/O

计算机并不区分二进制文件与文本文件,所有的文件都是以二进制形式来存储的,二进制I/O不涉及编码和解码,因此比文本I/O更加高效。

17.4 二进制I/O类

InputStream类是二进制输入类的根类,而OutputStream类是二进制输出类的根类

二进制I/O类中的所有方法都声明为抛出java.io.IOException或其子类

在这里插入图片描述

17.4.1 FilelnputStream和FileOutputStream

FilelnputStream类用来从文件中读取数据,FileOutputStream类用来向文件中写入数据

import java.io.*;

public class Test {
  public static void main(String[] args) throws java.io.IOException {
	  FileOutputStream output = new FileOutputStream("Exercise17_01.txt");
	  int randomInt = 65;
	  output.write(randomInt);
	  output.close();
	  
	  FileInputStream input = new FileInputStream("Exercise17_01.txt");
	  System.out.print(input.read());
	  input.close();
  }
}

write()方法接收一个byte类型的参数,且这个参数忽略符号位,因此,参数的范围是0-255(1个byte是8个bit,因此就是8个0或1,最大能表示255)

如果输入的参数是0-255之间的数字,就会将这个数字储存进文件,如果输入的参数是负数,或者大于255,这个参数就会被截断,只保留后8位

如果现在你去看Exercise17_01.txt文件本身,就会发现文件内容是A,这是因为,虽然各种二进制类的方法本身不涉及编码和解码,但是文本编辑器进行了ASCII解码,让用户看到解码后的对应字符

需要注意的是,用于进行二进制数据输入输出的类,并不会将数据按照文本的形式保存到文件中,有时可能会出现乱码,因此,我们有的时候确实写入了数据,只不过由于编译器的编码方案等局限,无法直接从文本编辑器查看内容

17.4.2 FilterlnputStream和FilterOutputStream

过滤器数据流可以用来读取某些特殊的字符(串),如基本数据类型和字符串

17.4.3 DatalnputStream和DataOutputStream

FilterlnputStream和FilterOutputStream是过滤数据的基类,例如,如果需要处理基本数值类型,就需要用到DatalnputStream类和DataOutputStream类

具体一点来说,我们刚刚学过,write()方法如果输入超出了范围0-255,就会被截断,为了避免截断,我们引入本节内容

如果文件读取到了末尾再次尝试读取,read()方法会返回-1,readInt()等方法就会发生EOFException异常

不同的数据写入时有自己特殊的编码方式,读取数据的类型取决于写入数据的类型,例如,如果一个文件不是由writeInt()创建的,直接读取readInt()可能会有异常

读取数据的顺序需要按照写入数据的顺序来进行,如果先写入了一个writeUTF,再写入了一个writeDouble,读取的时候也必须先读取writeUTF,再读取writeDouble,直接读取writeDouble会报异常

17.4.4 BufferedlnputStream和BufferedOutputStream

BufferedlnputStream类和BufferedOutputStream类可以通过减少磁盘读写次数来提高输人和输出的速度

17.5 示例学习:复制文件
17.6 对象 I/O

ObjectlnputStream类和ObjectOutputStream类除了可以实现基本数据类型与字符串的输入和输出之外,还可以实现对象的输入和输出。由于ObjectlnputStream类和ObjectOutputStream类包含DatalnputStream类和DataOutputStream类的所有功能,所以,完全可以代替

写入/读取流中的对象需要是可序列化的,因为可序列化的对象是java.io.Serializable接口的实例,所以可序列化对象的类必须实现Serializable接口(基本类型在进行序列化时会被自动拆箱/装箱并通过)

如果一个对象是Serializable的实例,但它包含了非序列化的实例数据域,对象就不是可序列化的,需要给这些数据域加上关键字transient, 告诉Java虚拟机将对象写入对象流时忽略这些数据域

17.7 随机访问文件

Java提供了RandomAccessFile类,允许从文件的任何位置进行数据的读写

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值