愿天堂没有Java之文件操作

JavaSE 笔记(七)

Java 是一门非常严谨的语言

File 类概述

认识一下嘛
  • 该类在 java.io.File 下,代表操作系统的文件对象(文件、文件夹)
  • 该类可以定位文件,获取文件信息,删除、创建文件(夹);但是不能读写文件
格式
  • 仅仅是一个路径名称,该路径可以存在,也可以不存在
1
File file = new ("pathname");
绝对路径与相对路径
  • 绝对路径:从盘符开始

    File file = new File("D:/poria/poria.txt");

  • 相对路径:不带盘符,默认直接到当前工程下寻找文件

    File file = new File("模块名称/poria.txt");

常用方法

判断文件类型、获取文件信息
方法名称 说明
public boolean isDirectory() 测试此抽象路径名表示的File是否为文件夹
public boolean isFile() 测试此抽象路径名表示的File是否为文件
public boolean exists() 测试此抽象路径名表示的File是否存在
public String getAbsolutePath() 返回此抽象路径名的绝对路径名字符串
public String getPath() 将此抽象路径名转换为路径名字符串
public String getName() 返回由此抽象路径名表示的文件或文件夹的名称
public long lastModified() 返回文件最后修改的时间毫秒值
创建文件
方法名称 说明
public boolean createNewFile() 创建一个新的空的文件
public boolean mkdir() 只能创建一级文件夹
public boolean mkdirs() 可以创建多级文件夹
删除文件
方法名称 说明
public boolean delete() 删除由此抽象路径名表示的文件或空文件夹
  • delete 方法默认只能删除文件和空文件夹
  • 该删除方法不走回收站
遍历文件夹
方法名称 说明
public String[] list() 获取当前目录下所有的一级文件名称到一个字符串数组中去返回。
public File[] listFiles()(常用) 获取当前目录下所有的一级文件对象到一个文件对象数组中去返回(重点)
  • listFIles 注意事项
    • 当调用者不存在时,返回 null
    • 当调用者是文件夹时,返回 null
    • 当调用者是一个空文件夹时,返回长度为0的数组
    • 当调用者是一个有内容的文件夹时,将里面所有的文件和文件夹的路径放在 File 数组中返回
    • 当调用者是一个有隐藏文件的文件夹时,会将所有内容返回,包括隐藏文件
    • 当调用者是一个有权限的文件夹时,返回 null

字符集

认识一下嘛
  • 计算机底层不可以直接存储字符,只能存储二进制
  • 二进制可以转化为十进制,十进制编号
  • 计算机可以给人类字符进行编号存储,这套编号规则就是字符集
常见字符集
  • ASCII
    • 美国信息交换标准码
    • 一个字节存储一个字符,一个字节是8位,即2的八次方,对于英文,数字够用
  • GBK
    • windows系统默认的码表,兼容 ASCII 码表,也包含几万汉字,并支持繁体汉字以及部分日韩文字
    • GBK 是中国的码表,一个中文以两个字节的形式存储
  • Unicode
    • 又称统一码,万国码,单一码
    • 容纳有世界上大多数国家的所有常见文字和符号
    • Unicode 会先通过 UTF-8,UTF-6 以及 UTF-32 的编码成二进制后再存储到计算机中
    • UTF-8 编码后一个中文一般以三个字节形式存储
编码解码方法
  • String 编码

    方法名称 说明
    byte[] getBytes() 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中
    byte[] getBytes(String charsetName) 使用指定的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中
  • String 解码

    构造器 说明
    String(byte[] bytes) 通过使用平台的默认字符集解码指定的字节数组来构造新的 String
    String(byte[] bytes, String charsetName) 通过指定的字符集解码指定的字节数组来构造新的 String

IO 流概述

认识一下嘛
  • IO 流也成为输入、输出流,就是用来读写数据的
  • I 表示 Input,是数据从磁盘文件读到内存的过程,称之为输入,负责读
  • O 表示 Output,是内存数据从内存写到磁盘文件的过程,称之为输出,负责写
分类
  • 字节流:操作所有类型的文件
  • 字符流:只能操作纯文本文件

字节流的使用

FileInputStream
构造器 说明
public FileInputStream(File file) 创建字节输入流管道与源文件对象接通
public FileInputStream(String pathname) 创建字节输入流管道与源文件路径接通
方法名称 说明
public int read() 每次读取一个字节返回,如果字节已经没有可读的返回-1
public int read(byte[] buffer) 每次读取一个字节数组返回,如果字节已经没有可读的返回-1
public byte[] readAllBytes() throws IOException 直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回
FileOutputStream
构造器 说明
public FileOutputStream(File file) 创建字节输出流管道与源文件对象接通
public FileOutputStream(File file,boolean append) 创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream(String filepath) 创建字节输出流管道与源文件路径接通
public FileOutputStream(String filepath,boolean append) 创建字节输出流管道与源文件路径接通,可追加数据
方法名称 说明
public void write(int a) 写一个字节出去
public void write(byte[] buffer) 写一个字节数组出去
public void write(byte[] buffer , int pos , int len) 写一个字节数组的一部分出去。
流的刷新与关闭
方法 说明
flush() 刷新流,还可以继续写数据
close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据

资源释放的方式

try-catch-finally
  • finally:在异常处理时,提供 finally 块来执行所有清除操作,比如 IO 流中的资源释放

  • 被 finally 控制的语句最终一定会执行,除非 JVM 退出

  • 格式

    1
    2
    3
    4
    5
    6
    7
    try{
    // 正常语句
    }catch (Expection e){
    e.printStackTrace();
    }finally{
    // 最终执行的语句
    }
  • 可以在 finally 块中最后释放资源

try-with-resource
  • 虽然上面的办法可以用于释放资源,但是释放的代码过于繁琐

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    InputStream is = null ;
    OutputStream os = null;
    try{
    ...
    }catch (Exception e){
    e.printStackTrace();
    } finally {
    // 关闭资源!
    try {
    if(os != null) os.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    try {
    if(is != null) is.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
  • 改进后的方案

    1
    2
    3
    4
    5
    6
    7
    定义输入流对象;
    定义输出流对象;
    try(输入流对象;输出流对象){
    可能出现异常的代码;
    }catch(异常类名 变量名){
    异常的处理代码;
    }
  • 注意:

    • try 后面的小括号只能放资源对象,否则就会报错
    • 所谓资源对象就是实现了 Closeable/AutoCloseable 接口的对象

字符流的使用

Reader
构造器 说明
public FileReader(File file) 创建字符输入流管道与源文件对象接通
public FileReader(String pathname) 创建字符输入流管道与源文件路径接通
方法名称 说明
public int read() 每次读取一个字符返回,如果字符已经没有可读的返回-1
public int read(char[] buffer) 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1
FileWriter
构造器 说明
public FileWriter(File file) 创建字符输出流管道与源文件对象接通
public FileWriter(File file,boolean append) 创建字符输出流管道与源文件对象接通,可追加数据
public FileWriter(String filepath) 创建字符输出流管道与源文件路径接通
public FileWriter(String filepath,boolean append) 创建字符输出流管道与源文件路径接通,可追加数据
方法名称 说明
void write(int c) 写一个字符
void write(char[] cbuf) 写入一个字符数组
void write(char[] cbuf, int off, int len) 写入字符数组的一部分
void write(String str) 写一个字符串
void write(String str, int off, int len) 写一个字符串的一部分
void write(int c) 写一个字符
流的刷新与关闭
方法 说明
flush() 刷新流,还可以继续写数据
close() 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据

缓冲流

认识一下嘛
  • 缓冲流也称为高级流、高效流
  • 缓冲流自带缓冲区、可以提高原始流独写数据的性能
字节缓冲流
  • BufferedInputStream & BufferedOutputStream 只是提高了性能,功能方法上并无变化

    构造器 说明
    public BufferedInputStream(InputStream is) 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能
    public BufferedOutputStream(OutputStream os) 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能
字符缓冲流
  • BufferedReader 除了提高性能外,还多了一个按行读取数据的功能

    构造器 说明
    public BufferedReader(Reader r) 可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道,从而提高字符输入流读数据的性能
    方法 说明
    public String readLine() 读取一行数据返回,如果读取没有完毕,无行可读返回null
  • BufferWriter 除了提高性能外,还多了一个换行的功能

    构造器 说明
    public BufferedWriter(Writer w) 可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能
    方法 说明
    public void newLine() 换行操作

转换流

引出
  • 如果代码编码和文件编码不一致,使用字符流直接读取会出现乱码
  • 使用转换流封装之后,可以避免这一问题
字符输入转换流
  • InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流

    构造器 说明
    public InputStreamReader(InputStream is) 可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用,与默认的FileReader一样。
    public InputStreamReader(InputStream is ,String charset) 可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中的字符就不乱码了(重点)
字符输出转换流
  • OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流

    构造器 说明
    public OutputStreamWriter(OutputStream os) 可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用。
    public OutputStreamWriter(OutputStream os,String charset) 可以把原始的字节输出流按照指定编码转换成字符输出流(重点)

序列化对象

对象序列化
  • 把内存中的对象存储到磁盘文件中去

  • 序列化的对象必须实现了序列化接口

  • 对象字节输出流:ObjectOutputStream

    构造器 说明
    public ObjectOutputStream(OutputStream out) 把低级字节输出流包装成高级的对象字节输出流
  • 序列化方法

    方法名称 说明
    public final void writeObject(Object obj) 把对象写出去到对象序列化流的文件中去
对象反序列化
  • 把磁盘文件中的对象恢复到内存中的对象

  • 对象字节输入流:ObjectInputStream

    构造器 说明
    public ObjectInputStream(InputStream out) 把低级字节输如流包装成高级的对象字节输入流
  • 反序列化方法

    方法名称 说明
    public Object readObject() 把存储到磁盘文件中去的对象数据恢复成内存中的对象返回

打印流

认识一下嘛
  • 该流可以实现方便、高效的打印数据到文件中去
  • 一般指 PrintStream,PrintWriter 两个类
  • 可以实现打印什么数据就是什么数据
PrintStream
构造器 说明
public PrintStream(OutputStream os) 打印流直接通向字节输出流管道
public PrintStream(File f) 打印流直接通向文件对象
public PrintStream(String filepath) 打印流直接通向文件路径
方法 说明
public void print(Xxx xx) 打印任意类型的数据出去
PrintWriter
构造器 说明
public PrintWriter(OutputStream os) 打印流直接通向字节输出流管道
public PrintWriter (Writer w) 打印流直接通向字符输出流管道
public PrintWriter (File f) 打印流直接通向文件对象
public PrintWriter (String filepath) 打印流直接通向文件路径
方法 说明
public void print(Xxx xx) 打印任意类型的数据出去
输出语句重定向
  • 属于打印流的一种应用,可以打印的位置改到指定位置

    1
    2
    PrintStream ps = new PrintStream("文件地址");
    System.setOut(ps);