文件流

image.png
文件在程序中是以流的形式来操作的
image.png
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源(文件)到程序(内存)的路径
输出流:数据从程序(内存)到数据源(文件)的路径

常用的文件操作

创建文件对象相关构造器和方法
image.png
new File(String pathname) //根据路径构建一个File对象image.png
new File(File parent, String child) //很根据父目录文件+子路径构建image.png
new File(String parent, String child) //根据父目录+子路径构建image.png
createNewFile //创建新文件
获取文件相关信息
getName、getAbsolutePath、getParent、length、exists、isFile、isDirectory
目录的操作和文件删除
mkdir //创建一级目录
mkdirs //创建多级目录
delete //删除空目录或文件

IO流原理及分类

IO流原理

  1. IO是Input/Output的缩写,I/O技术是非常实用的技术,用于处理数据传输。如读/写文件,网络通讯等
  2. Java程序中,对于数据的輪入输出操作以“流(stream)”的方式进行
  3. java.io包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过方法输入或输出数据
  4. 输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中
  5. 输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中

image.png

流的分类

按操作数据单位不同分为:字节流(8bit)操作二进制文件,字符流(按字符)操作文本文件
按数据流的流向不同分为:输入流,输出流
按流的角色的不同分为:节点流,处理流/包装流
image.png

  1. Java的流共涉及40多个类,实际上非常规则,都是从如上4个抽象基类派生的
  2. 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀

    体系图

    InputStream: OutPutStream:
    image.png image.png
    Reader: Writer:
    image.png image.png
    image.png

    字节输入流 InputStream

    InputStream抽象类是所有字节输入流的超类
    InputStream常用的子类:

  3. FileInputStream:文件输入流

  4. BufferedInputStream:缓冲字节输入流
  5. ObjectInputStream:对象字节输入流

    FileInputStream 和 FileOutputStream

    FileInputStream

    image.png
    image.png
    read()方法读取一个字节,返回-1表示读取完毕,此方法返回ascll码image.png
    read(byte[] b)方法读取最多b.length长度的数据到字节数组,返回-1表示读取完毕。超过b.length每次都会读b.length个,不足的读实际读取的字节数。此方法返回读取长度image.png

    FileOutputStream

    image.png
    image.png
    image.png

    FileReader 和 FileWriter

    FileReader 和 FileWriter 是字符流,即按照字符来操作

    FileReader

    image.png
    image.png
    Filereader相关方法:

  6. new FileReader(File/String)

  7. read:每次读取单个字符,返回该字符,如果到文件末尾返回-1
  8. read(char[]):批量读取多个字符到数组,返回读取到的字符数,如果到文件末尾则返回-1

相关API:

  1. new String(char[]):将char[]转换成String
  2. new String(char[], off, len):将char的指定部分转换成String

    FileWriter

    image.png
    image.png
    FileWriter常用方法:

  3. new FileWriter(File/String):覆盖模式

  4. new FileWriter(File/String, true):追加写入模式
  5. write(int):写入单个字符
  6. write(char[]):写入指定数组
  7. write(char, off, len):写入指定数组的指定部分
  8. write(string):写入整个字符串
  9. write(string, off, len):写入字符串的指定部分

相关API:
String类:toCharArray:将String转换成char[]
注意:
FileWriter使用后,必须要关闭(close)或刷新(flush),否则写入不到指定文件

节点流和处理流

基本介绍:

  1. 节点流可以从一个特定的数据源读写数据,如FileReader、FileWriter
  2. 处理流(包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写功能,也更加灵活,如BufferedReader、BufferedWriter

image.png

处理流:以BufferedReader为例

image.png
BufferedReader类中,有属性Reader,即可以封装一个节点流,该节点流可以是任意的,只要是Reader的子类。同理,BufferedWriter也有Writer类型属性。
BufferedInputStream 和 BufferedOutputStream 也分别有InputStream类型属性和OutputStream类型属性,但不在本类中,而是通过其父类继承而来image.pngimage.png

image.png
而节点流,不同类型的文件需要用不同的节点流
image.png

节点流和处理流的区别和联系

  1. 节点流是底层流/低级流,直接和数据源相接
  2. 处理流(包装流)包装节点流,既可以消除不同节点的实现差异,也可以提供更方便的方法来完成输入输出
  3. 处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连

处理流的功能主要体现在以下两个方面:

  1. 性能的提高:主要以增加缓冲的方式来提高输入输出的效率。
  2. 操作的便捷:处理流可能提供了一系列便捷的方法来一次输入输出大批量的数据,使用更加灵活方便

    修饰器设计模式

    父类抽象类Reader,写入子类空方法(非抽象方法不用继承),readFile,readString等,或用read()统一管理
    image.png
    节点流子类FileReader,StringReader,继承Reader,有各自的方法
    image.png
    image.png
    处理流BufferReader,继承Reader,含有成员Reader reader,可以接收任意Reader子类,并直接调用对应方法
    image.png

    BufferedReader 和 BufferedWriter

    BufferedReader和BufferedWriter属于字符流,是按照字符来读取数据的
    关闭时,只需关闭外层流即可。因为Buffered是包装流,在底层,实际操作数据的还是节点流,关闭包装流会自动关闭节点流。Buffered的Close()实际调用的是节点流的close,in为传入的new FileReader(filePath)
    image.png

    BufferedReader

    image.png

    BufferedWriter

    image.png
    追加写入模式需要在传入的new FileWriter(filePath, true)写入,因为包装流在底层实际操作数据的还是节点流

    BufferedInputStream 和 BufferedOutputStream

    BufferedInputStream

    image.png
    BufferedInputStream是字节流,在创建BufferedInputStream时,会创建一个内部缓冲区数组
    image.png

    BufferedOutputStream

    image.png
    BufferedOutputStream是字节流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统
    image.png

    ObjectInputStream 和 ObjectOutputStream

    对象流

    序列化和反序列化

  3. 序列化就是在保存数据时,保存数据的值和数据爕型

  4. 反序列化就是在恢复数据时,恢复数据的值和数据类型
  5. 需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

Serializable //这是一个标记接口,没有方法
Externalizable //该接口有方法需要实现,因此我们一般实现上面的
基本介绍:
image.png image.png

  1. 功能:提供了对基本数据类型或对象类型的序列化和反序列化的方法
  2. ObjectOutputStream提供序列化功能
  3. ObjectInputStream提供反序列化功能

image.png image.png

ObjectOutputStream

image.png

ObjectInputStream

image.png
image.png
如果希望调用dog的方法,需要在此处可以访问到Dog类

注意事项和细节说明

  1. 读写顺序要一致
  2. 要求序列化或反序列化对象,需要实现Serializable
  3. 序列化的类中建议添加SerialversionUID,为了提高版本的兼容性
  4. 序列化对象时,默认将里面所有属性都进行序列化,但除了static或transient修饰的成员
  5. 序列化对象时,要求里面属性的类型也需要实现序列化接口
  6. 序列化具备可继承性,也就是如果某类已经实现了序列化,则它的所有子类也已经默认实现了序列化

    标准输入输出流

    基本介绍:
    类型 默认设备
    System.in 标准输入 InputStream 键盘
    System.out 标准输出 PrintStream 显示器
    image.png

    InputStreamReader 和 OutputStreamWriter

    转换流
    基本介绍:

  7. InputStreamReader:Reader的子类,可以将Inputstream(字节流)包
    装(转换)成 Reader(字符流)

  8. OutputStreamWriter:Writer的子类,实现将OutputStream(字节流)包装成 Writer(字符流)
  9. 当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文乱码问题,所以建议将字节流转换成字符流
  10. 可以在使用时指定編码格式(比如utf-8,gbk,gb2312,lSO8859-1等)

image.png image.png
应用案例:

  1. 将字节流FileInputStream包装(转换)成字符流InputStreamReader,对文件按照 utf-8/gbk/… 格式进行读取,进而再包装成BufferedReader

image.png

  1. 将字节流FileOutputStream包装(转换)成字符流OutputStreamWriter,对文件按照 gbk/utf-8/… 格式进行写入

image.png

PrintStream 和 PrintWriter

字节打印流 和 字符打印流
打印流只有输出流,没有输入流
image.png image.png

PrintStream

image.png
print底层输出使用的是write(),可以直接调用write打印/输出
image.png

PrintWriter

image.png