第11章 IO流

简介: 流的分类及使用场景,暂未包含使用举例。

11.1 文件

11.1.1 文件流

  1. 流:数据在数据源(文件)和程序(内存)之间经历的路径
  2. 输入流:数据从数据源(文件)到程序(内存)的路径
  3. 输出流:数据从程序(内存)到数据源(文件)的路径

11.1.2 常用操作

  1. 创建文件对象
  • new File(String str):通过指定路径创建File实例
  • File(File parent, String child):通过父目录文件和子路径搭配创建File实例
  • File(String parent, String child):通过父目录和子路径搭配创建File实例
  1. 获取文件相关信息
  • createNewFile():在指定路径生成目标文件,并保存在磁盘里
  • 该方法有异常问题
  • getName():获取文件名
  • getAbsolutePath():获取文件的绝对路径(带文件名)
  • getParent():获取父级目录
  • length()获取文件内容有多少字节,根据文件的编码获取
  • UTF-8编码中,汉字3个字节
  • exists():文件是否存在
  • isFile():是不是一个文件
  • isDirectory():是不是一个目录
  1. 目录操作和文件删除:
  • delete():删除文件或空文件夹
  • mkdir():创建一级目录
  • mkdirs():创建多级目录

11.2 IO流原理及分类

11.2.1 I/O流原理

  1. 用于数据传输,如读写文件,网络通讯。
  2. java.io包下提供了各种流(stream)类和接口,用以获取不同类的数据,并通过方法输入或输出数据。
  3. 输入input:读取外部数据到内存(程序)中
  4. 输出output:将程序(内存)中的数据输出到存储设备中。

11.2.2 流的分类:写、out:自身→外部,读、input:外部→自身

  1. 按照操作数据单位分:字节流(8字节)二进制文件、字符流(按字符)文本文件
  2. 按数据流向:输入流、输出流
  3. 按流的角色:节点流、处理流/包装流
  • 节点流:从一个特定的数据源读写数据
  • 数据源:存放数据的地方,可以是文件、字符串、数组、管道
  • 处理流/包装流:建立在已有的流之上,为程序提供更强大、更灵活的读写功能
  • 如BufferedReader、BufferedWriter
  • 处理流类的底层封装了节点流的Wrtie或Reader对象,根据多态,可以使用各种Writer和Reader的子类对象

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

  • 节点流是底层流,直接更数据源相接
  • 处理流包装节点流,可以消除不同节点流的实现差异,也可以提供更方便的方法完成输入输出
  • 处理流对节点流的包装,使用了修饰器涉及模式,不会直接与数据源相连
  • 处理流提高了性能:主要以增加缓冲的方式提高输入输出的效率
  • 处理流提供了操作的便捷:处理流可能提供了一系列编辑的方法来一次输入输出大批量的数据,使用更加灵活方便。

抽象基类

字节流

字符流

输入流

InputStream

Reader

输出流

OutputStream

Writer

  • java的io流涉及40多个类,都是从上述4个抽象基类派生而来
  • 这4个基类派生出来的子类名称都是以基类名作为子类名的后缀
  1. IO流体系图

11.3 节点流/文件流

11.3.1 FileInputStream

  1. 创建文件输入流对象:new FileInputStream(filePath)
  • 有异常问题
  1. read():从输入流中读取一个字节的数据,
  • 到达文件末尾时,返回-1(读取完毕)
  • 有异常问题
  • 读入的字节数据是ASCII编码,使用字符强转可得到原文
  1. read(byte[] b):一次读取b.length()个字节存入到b中,返回实际读取的字节数量
  • 到达文件末尾时,返回-1(读取完毕)
  • 有异常问题
  • 读入的字节数据是ASCII编码组成的数组,转换为字符串时可使用String(byte[] bytes, int offset, int length)构造器
  • offset:byte[]数组起点下标
  • length:读入byte[]字节长度
  1. read(byte[] b, int off, int len)开发中使用这个
  • 到达文件末尾时,返回-1(读取完毕)
  • 有异常问题
  1. close():关闭文件输入流,并释放与该流相关的所有系统资源
  • 由于创建输入流对象有异常问题,该方法须在finally块中调用,以保证确实执行。

11.3.2 FileOutputStream

  1. 创建文件输出流对象:
  • new FileOutputStream(filePath):覆盖模式
  • new FileOutputStream(filePath, true):追加模式:第二个参数设置为true时,输出的字节流是追加的方式
  • 有异常问题
  1. write(int b):将单个字节数据输出到输出流,传入的是一个ASCII整数,或者一个字符(会自动类型转换为整型)
  • 有异常问题
  1. write(byte[] b):将b.length()个字节输出到输出流
  • 有异常问题
  • 可搭配String的getBytes(str)使用,将字符串转换为字符数组
  1. write(byte[] b, int off, int len):将字节数组b,从下标off开始的len个字节数据输出到输出流。开发中使用这个
  • 有异常问题
  1. close():关闭文件输出流,并释放与该流相关的所有系统资源
  • 由于创建输出流对象有异常问题,该方法须在finally块中调用,以保证确实执行。

11.3.3 文件拷贝

  1. 搭配输入输出流使用

11.3.4 FileReader

  1. 创建文件读取对象:new FileReader(filePath)
  • 有异常问题
  1. reader():读取单个字符,读入的是个整数
  • 到达文件末尾时,返回-1(读取完毕)
  • 有异常问题
  • 读入的字符数据是ASCII编码,使用字符强转可得到原文
  1. read(byte[] b):一次读取b.length()个字符存入到b中,返回实际读取的字符数量
  • 到达文件末尾时,返回-1(读取完毕)
  • 有异常问题
  • 读入的字符数据是ASCII编码组成的数组,转换为字符串时可使用String(char[] chars, int offset, int length)构造器
  • offset:char[]数组起点下标
  • length:读入char[]字节长度
  1. read(char[] b, int off, int len)开发中使用这个
  • 到达文件末尾时,返回-1(读取完毕)
  • 有异常问题
  1. close():关闭文件读取对象,并释放与该流相关的所有系统资源
  • 由于创建文件读取对象有异常问题,该方法须在finally块中调用,以保证确实执行。

11.3.5 FileWrite

  1. 创建文件写入流对象:
  • new FileWriter(filePath):覆盖模式
  • new FileWriter(filePath, true):追加模式:第二个参数设置为true
  • 有异常问题
  1. write(int b):将单个字符数据输出到输出流,传入的是一个ASCII整数,或者一个字符(会自动类型转换为整型)
  • 有异常问题
  1. write(char[] b):将b.length()个字符输出到输出流
  • 有异常问题
  1. write(char[] b, int off, int len):将字符数组b,从下标off开始的len个字符数据输出到输出流。开发中使用这个
  • 有异常问题
  1. write(String str):写入整个字符串
  2. write(String str, int off, int len):写入字符串指定部分
  3. close():关闭文件输出流,并释放与该流相关的所有系统资源
  • 由于创建输出流对象有异常问题,该方法须在finally块中调用,以保证确实执行。
  • FileWtrie必须关闭流(close())或(flush(),否则不能真正保存到文件
  • 等价于flush()和关闭

11.4 处理流

  • BufferedReader和BufferedWriter
  • 属于字符流,一般用于处理文本文件,处理声音、视频、doc、pdf等二进制文件时有数据丢失的风险。
  • 关闭流时,只需要关闭外层的BufferedReader或BufferedWriter即可,而不是传入的Reader、Writer对象,底层会自动关闭对应的传入Reader、Writer对象
  • BufferedInputStream和BufferedOutputStream
  • 属于字节流,既可处理文本文件,也可处理二进制文件

11.4.1 BufferedReader

  1. 创建对象:new BufferedReader(Reader in)
  • 有异常问题。
  • 异常存在于传入的Reader in对象
  1. readLine():按行读取,读取完毕返回null
  • 不读入换行

11.5.2 BufferedWriter

  1. 创建对象:new BufferedWriter(Writer out)
  • 有异常问题。
  • 异常存在于传入的Writer out对象
  1. write(String s, int off, int len):写入字符串的一部分
  • 好像不要off和len的时候是传入整个字符串?
  1. newLine():插入一个和系统相关的换行符

11.4.3 BufferedInputStream

  • new BufferedInputStream(InputStream in)
  • 类似BufferedReader
  • 使用的方法是:read(byte[] b, int off, int len)

11.4.4 BufferedOutputStream

  • new BufferedOutputStream(OutputStream out)
  • 类似于BufferedWriter
  • 使用的方法是:write(byte[] b, int off, int len)

11.4.5 序列化和反序列化

  1. 序列化:保存值和数据类型到文件
  2. 反序列化:将保存到文件的数据值和数据类型进行恢复
  3. 对象要可序列化,则要求该对象实现SerializableExternalizable接口。
  • 一般使用Serializable,该接口为标记接口——没有任何属性和方法
  • Externalizable,继承自Serializable,需要重写两个方法
  1. 注意事项
  • 读写顺序要一致
  • 序列化或反序列化的对象必须实现SerializableExternalizable接口。
  • 序列化的对象建议添加private static final long serialVersionUID,提高兼容性
  • 序列化的对象,会默认初始化除static和transient修饰的成员
  • 序列化的对象,其属性类型也需要实现序列化接口,有异常问题
  • 序列化具有继承性,其子类自动可序列化

11.4.6 ObjectOutputStream

  1. 特征:字节流、处理流、对象流、提供序列化功能
  2. 创建对象:new ObjectOutputStream(OutputStream out)
  3. writeInt(int):自动装箱,写一个32位的整形数
  4. writeBoolean(boolean):自动装箱
  5. writeChar(int):自动装箱,写一个16位字符,可传入字符,会自动转换为int
  6. writeDouble(double):自动装箱,写一个64位双精度浮点数
  7. writeUTF(String):以UTF-8模式写入字符串
  8. writeObject(Object):将指定对象写入
  9. close()
  10. 上述均有异常问题。

11.4.7 ObjectInputStream

  1. 特征:字节流、处理流、对象流、提供反序列化功能,反序列化顺序必须与序列化顺序一致。
  2. 创建对象:new ObjectInputStream(InputStream input)
  3. readInt()
  4. readBoolean()
  5. readChar()
  6. readDouble()
  7. readUTF()
  8. readObject():底层表现多塔的特征,编译类型是Object,运行类型是实际的类型,底层会进行造型和强转。但如果使用运行类型的方法,需要进行显式强转。
  9. close()
  10. 上述均有异常问题

11.5 标准输入流和输出流(java.lang.Object)

  1. System.in类:编译类型为InputStream、运行类型为BufferedInputStream
  • 标准输入
  • 输入源键盘
  • 返回InputStream
  1. System.out类:编译类型为PrintStream、运行类型为PrintStream
  • 标准输出
  • 输出源显示器
  • 返回OutputStream

11.6 转换流

  • InputStreamReader(字符流):
  • 默认情况下,读取文件时按照utf-8的形式,
  • Reader的子类
  • 可以将InputStream(字节流)包装成/转换成Reader(字符流)
  • InputStreamReader(InputStream in, Charset cs):按照读取文件的cs编码格式进行读入
  • OutputStreamWriter(字符流):
  • 指定处理编码
  • Writer的子类
  • 可以将OutputStream(字节流)转换成Writer(字符流)
  • OutputStreamReader(OutputStream in, Charset cs)
  • 主要用于解决中文文本数据
  • 中文文本数据有乱码问题
  • 中文文本按照字符流处理(读取和写入)效率更高

11.7 打印流

  • 只有输出流没有输入流

11.7.1 PrintStream

  1. 构造器(常用):
  • PrintStream(OutputStream out)
  • PrintStream(System.out):默认屏幕输出
  • PrintStream(File file):可指定编码
  • PrintStream(String fileName):可指定编码
  • PrintStream(Writer out):可指定编码
  1. 使用:PrintStream out = System.out
  • out.print():默认情况下,输出位置是标准输出——显示器
  • print()底层使用的是write(),故可以使用字节流的write()方法进行时输出
  • 修改输出位置:System.setOut(PrintStream ps),然后调用out.print()
  • 根据创建的ps对象,可以输出到指定文件
  1. 需要关闭。

11.7.2 PrintWriter

  1. 构造器:
  • PrintWriter(OutputStream out)
  • PrintWriter(System.out):默认屏幕输出
  • PrintWriter(File file):可指定编码
  • PrintWriter(String fileName):可指定编码
  • PrintWriter(Writer out):可指定编码
  1. 使用:
  • 调用print()方法
  1. 需要关闭。

11.8 Properties

  1. 作用:专门用于读写配置文件的集合类
  • 配置文件格式:键=值
  • 键值对不需要有空格
  • 值不需要使用引号
  • 默认类型为String
  1. 创建对象:new Properties()
  2. 常见方法:
  • load(Reader reader)
  • loaad(InputStream instream):加载配置文件
  • list(PrintWriter out):将此属性列表打印到指定的输出流(键值对的形式)
  • list(System.out):屏幕输出
  • list(PrintStream out)
  • getProperty(String key):根据key获取value
  • setProperty(String key, String value):修改、添加键值对到Properties类的对象(此时还没添加到文件里)
  • store(OutputStream out, String comments):将k-v存储到文件中
  • comments会添加文件的开头,以#注释,一般可置为null
  • store(Writer writer, String comments)
  1. IDEA中使用路径:
  • 绝对路径
  • 工程路径:src/io.properties
  • 模块路径:模块名/src/io.properties
目录
相关文章
|
3月前
|
C语言 iOS开发 C++
10. C++IO流
10. C++IO流
26 0
|
4天前
|
Java
|
3月前
|
算法 C语言 C++
【C++】C++的IO流
【C++】C++的IO流
|
3月前
|
存储 Java
IO流知识篇
IO流知识篇
|
3月前
|
安全 C语言 C++
【C++】—— C++的IO流
【C++】—— C++的IO流
|
C语言 C++ iOS开发
IO流(C++)
IO流(C++)
68 0
IO流(C++)
io流
inputStream和Reader是所有输入流的基类
|
8月前
|
算法 C语言 C++
C++的IO流
C++的IO流
35 0
|
12月前
|
安全 编译器 C语言
【C++】IO流
【C++】IO流
64 0