文件流
文件在程序中是以流的形式来操作的
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径
常用的文件操作
创建文件对象相关构造器和方法
new File(String pathname) //根据路径构建一个File对象
new File(File parent, String child) //很根据父目录文件+子路径构建
new File(String parent, String child) //根据父目录+子路径构建
createNewFile //创建新文件
获取文件相关信息
getName、getAbsolutePath、getParent、length、exists、isFile、isDirectory
目录的操作和文件删除
mkdir //创建一级目录
mkdirs //创建多级目录
delete //删除空目录或文件
IO流原理及分类
IO流原理
- IO是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等
- Java程序中,对于数据的輪入输出操作以“流(stream)”的方式进行
- java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据
- 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
- 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中
流的分类
按操作数据单位不同分为:字节流(8bit)操作二进制文件,字符流(按字符)操作文本文件
按数据流的流向不同分为:输入流,输出流
按流的角色的不同分为:节点流,处理流/包装流
- Java的流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的
-
体系图
InputStream: OutPutStream:
Reader: Writer:字节输入流 InputStream
InputStream抽象类是所有字节输入流的超类
InputStream常用的子类: FileInputStream:文件输入流
- BufferedInputStream:缓冲字节输入流
-
FileInputStream 和 FileOutputStream
FileInputStream
read()方法读取一个字节,返回-1表示读取完毕,此方法返回ascll码
read(byte[] b)方法读取最多b.length长度的数据到字节数组,返回-1表示读取完毕。超过b.length每次都会读b.length个,不足的读实际读取的字节数。此方法返回读取长度FileOutputStream
FileReader 和 FileWriter
FileReader 和 FileWriter 是字符流,即按照字符来操作
FileReader
Filereader相关方法: new FileReader(File/String)
- read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
- read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾则返回-1
相关API:
- new String(char[]):将char[]转换成String
new String(char[], off, len):将char的指定部分转换成String
FileWriter
FileWriter常用方法:new FileWriter(File/String):覆盖模式
- new FileWriter(File/String, true):追加写入模式
- write(int):写入单个字符
- write(char[]):写入指定数组
- write(char, off, len):写入指定数组的指定部分
- write(string):写入整个字符串
- write(string, off, len):写入字符串的指定部分
相关API:
String类:toCharArray:将String转换成char[]
注意:
FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定文件
节点流和处理流
基本介绍:
- 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
- 处理流(包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter
处理流:以BufferedReader为例
BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的,只要是Reader的子类。同理,BufferedWriter也有Writer类型属性。
BufferedInputStream 和 BufferedOutputStream 也分别有InputStream类型属性和OutputStream类型属性,但不在本类中,而是通过其父类继承而来
节点流和处理流的区别和联系
- 节点流是底层流/低级流,直接和数据源相接
- 处理流(包装流)包装节点流,既可以消除不同节点的实现差异,也可以提供更方便的方法来完成输入输出
- 处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连
处理流的功能主要体现在以下两个方面:
- 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便
修饰器设计模式
父类抽象类Reader,写入子类空方法(非抽象方法不用继承),readFile,readString等,或用read()统一管理
节点流子类FileReader,StringReader,继承Reader,有各自的方法
处理流BufferReader,继承Reader,含有成员Reader reader,可以接收任意Reader子类,并直接调用对应方法BufferedReader 和 BufferedWriter
BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的
关闭时,只需关闭外层流即可。因为Buffered是包装流,在底层,实际操作数据的还是节点流,关闭包装流会自动关闭节点流。Buffered的Close()实际调用的是节点流的close,in为传入的new FileReader(filePath)BufferedReader
BufferedWriter
追加写入模式需要在传入的new FileWriter(filePath, true)写入,因为包装流在底层实际操作数据的还是节点流BufferedInputStream 和 BufferedOutputStream
BufferedInputStream
BufferedInputStream是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数组BufferedOutputStream
BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统ObjectInputStream 和 ObjectOutputStream
序列化和反序列化
序列化就是在保存数据时,保存数据的值和数据爕型
- 反序列化就是在恢复数据时,恢复数据的值和数据类型
- 需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:
Serializable //这是一个标记接口,没有方法
Externalizable //该接口有方法需要实现,因此我们一般实现上面的
基本介绍:
- 功能:提供了对基本数据类型或对象类型的序列化和反序列化的方法
- ObjectOutputStream提供序列化功能
- ObjectInputStream提供反序列化功能
ObjectOutputStream
ObjectInputStream
注意事项和细节说明
- 读写顺序要一致
- 要求序列化或反序列化对象,需要实现Serializable
- 序列化的类中建议添加SerialversionUID,为了提高版本的兼容性
- 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
- 序列化对象时,要求里面属性的类型也需要实现序列化接口
序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化
标准输入输出流
基本介绍:
类型 默认设备
System.in 标准输入 InputStream 键盘
System.out 标准输出 PrintStream 显示器InputStreamReader 和 OutputStreamWriter
转换流
基本介绍:InputStreamReader:Reader的子类,可以将Inputstream(字节流)包
装(转换)成 Reader(字符流)- OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成 Writer(字符流)
- 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文乱码问题,所以建议将字节流转换成字符流
- 可以在使用时指定編码格式(比如utf-8,gbk,gb2312,lSO8859-1等)
应用案例:
- 将字节流FileInputStream包装(转换)成字符流InputStreamReader,对文件按照 utf-8/gbk/… 格式进行读取,进而再包装成BufferedReader
- 将字节流FileOutputStream包装(转换)成字符流OutputStreamWriter,对文件按照 gbk/utf-8/… 格式进行写入
PrintStream 和 PrintWriter
PrintStream
print底层输出使用的是write(),可以直接调用write打印/输出