Java IO
File
- File:是文件和目录路径名的抽象表示
- 文件和目录是可以通过File封装成对象的
- 对于File而言,其封装的并不是一个真正存在的文件,仅仅为一个路径名而已。它可以是存在的,也可以是不存在的。将来要通过具体的操作把这个路径的内容转换为具体存在的
构造方法
创建功能
删除功能
判断和获取功能
递归
- 以编程的角度来看,递归指的是方法定义中调用方法本身的现象
- 递归解决问题的思路:
- 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来解
- 递归策略只需少量的程序就能描述出解题过程所需要的多次重复计算
- 递归解决问题要找到的两个内容:
- 递归出口:否则会出现内存溢出
- 递归规则:与原问题相似的规模较小的问题
IO流
- IO:输入/输出(Input/Output)
- 流:是一种抽象概念,是对数据传输的总成。也就是说数据在设备间的传输称为流,流的本质为数据传输
- IO流就是用来处理设备间数据传输问题的
- 常见的应用:文件复制;文件长传;文件下载
- IO流按照数据类型分为字节流(字节输入流/字节输出流)和字符流(字符输入流/字符输出流)
- 如果数据通过记事本打开可以读懂里面的内容,就使用字符流,否则使用字节流
字节流
- 字节流抽象基类
- InputStream:这个抽象类表示字节输入流的所有类的超类
- OutputStream:这个抽象类表示字节输出流的所有类的超类
- 子类名特点:子类名称都是以其父类名作为子类名的后缀
- FileOutputStream:文件输出流用于将数据写入File
- FileOutputStream(String name):创建文件输出流以制定的名称写入文件
- 使用字节输出流写数据的步骤
- 创建字节输出流对象(调用系统功能创建文件,创建字节输出流对象,让字节输出流对象指向文件)
- 调用字节输出流对象的写数据方法
- 释放资源(关闭此文件输出流病释放与此相关联的任何系统资源)
- FileInputStream:将文件内容读取出来
- FileInputStream(String name):通过打开与实际文件的连接创建一个对象,该文件由文件系统中的路径名与name命名
- 使用字节输入流读数据的步骤
- 创建字节输入流对象
- 调用字节输入流对象的读数据方法
- 释放资源
字节流写数据的方法
- 字节流写数据换行
- Windows:‘\r\n’
- Linux:’\n’
- Mac:’\r’
- 字节流写数据追加
- 使用构造方法FileOutputStream(String name, boolean append)
字节缓冲流
- 字节缓冲流可提高效率
- BufferedOutputStream:该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致低层系统的调用
- BufferedOutputStream(OutputStream out)
- BufferedInputStream:创建BufferedInputStream将创建一个内部缓冲区数组。当从流中读取或跳过字节时,内部缓冲区将根据需要从所包含的输入流中重新填充,一次很多字节
- BufferedInputStream(InputStream in)
- 字节缓冲流仅仅提供缓冲区,而真正读写数据还要依靠基本的字节流对象进行操作
异常处理
- finally:在异常处理时提供finally块来执行所有清除操作。比如说IO流中的释放资源(被finally控制的语句一定会执行,除非JVM退出)
字符流
- 汉字的存储
- GBK编码,占用2个字节
- UTF-8编码,占用3个字节
- 无论采用什么存储方式,汉字的第一个字节均为负数(字节流复制文件时自动拼接)
- 字符流=字节流+编码表
- 编码表
- 计算机中存储的数据都是用二进制表示的
- 按照某种规则,将字符存储到计算机中,称为编码;将存储在计算机中的二进制数按照某种规则解析出来,成为解码
- 采用何种规则编码,就要采用何种规则解码,不然就会出现乱码
- 字符编码就是一套自然语言的字符与二进制数之间的对应规则
编码解码
- 字符串
- 编码:byte[] getBytes() byte[] getBytes(String charseName)
- 解码:String(byte[] bytes) String(byte[] bytes, String charseName)
- 字符流
- Reader:字符输入流的抽象类
- InputStreamReader------FileReader
- Writer:字符输出流的抽象类
- OutputStreamWriter------FileWriter
- Reader:字符输入流的抽象类
字符缓冲流
- 类
- BufferedWriter
- BufferedReader
- 特有功能
- void newLine():写一行行分隔符,分隔符字符由系统属性定义
- public String readLine():读一行文字,结果包含行的内容字符串,不包含任何终止字符,若到达结尾,则返回null
特殊操作流
标准输入输出流
- System类中有两个静态成员变量:
- public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
- new Scanner(System.in)
- public static final OutputStream out:标准输出流。通常该流对应于显示输出或由主机环境或用户指定的另一个输出目标
- System.out
- public static final InputStream in:标准输入流。通常该流对应于键盘输入或由主机环境或用户指定的另一个输入源
打印流
- 打印流分类
- 字节打印流:PrintStream
- 字符打印流:PrintWriter
- 打印流特点:
- 只负责输出数据,不负责读取数据
- 有自己的特有方法(print/println)
- 使用继承父类的方法写数据,查看时会转码;使用自己的特有方法写数据,查看的数据会原样输出
对象序列化流
-
对象序列化:将对象保存到磁盘中,或在网络中传输对象(写入文件后,相当于文件中持久保存了一个对象信息)
- 使用一个字节序列表示一个对象,该对象序列包含:对象类型、对象数据和对象中储存的属性等信息
- ObjectOutputStream
-
对象反序列化:将字节序列从文件中读取回来,重构对象
- ObjectInputStream
-
一个对象想要被序列化,该对象所属的类必须实现Serializable接口(Serializable是一个标记接口,实现该接口不需要重写任何方法)
-
用对象序列化流序列化一个对象后,加入修改了对象所属的类文件,读取数据是否会出现问题?如何解决?
-
InvalidClassException异常(类的细节改变导致默认生成的SerialVersionID值发生改变)
- 类的串行版本与从流中读取的类描述符的类型不匹配
- 该类包含位置的数据类型
- 该类没有可访问的无参构造函数
-
在对象所属的类中,显示声明SerialVersionID值(static final long serialVersionID = 42L)
-
-
如果一个对象中的某个成员变量的值不想被序列化,如何实现?
- 使用transient关键字修饰的成员变量不参与序列化过程(例:private transient int age)
Properties
- Properties是一个Map体系的集合类
- Properties可以保存到流中或从流中加载