javase IO

2018-07-17

IO概述

  • 当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
  • 当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
  • 因此我们把这种输入和输出动作称为IO操作。

常用接口与类

继承树

  • File类
  • 字节流
    • OutputStream抽象类
      • FileOutputStream类
      • ObjectOutputStream类
        • BufferedOutputStream类(缓冲流)
    • InputStream抽象类
      • FileInputStream类
      • ObjectInputStream类
        • BufferedInputStream类(缓冲流)
  • 字符流
    • Writer抽象类
      • BufferedWriter类(缓冲流)
      • OutputStreamWriter类(转换流)
        • FileWriter类
    • Reader抽象类
      • BufferedReader类
      • InputStreamReader类(转换流)
        • FileReader类(缓冲流)

图示

java io

总结

  • 文件的通用读写方式是字节流
  • 字符流(ReaderWriter)专门用于文本文件的读写(因为非文本文件中没有字符的概念)
    • 如果确定文本文件是采用的默认编码表,那么直接使用FileReaderFileWriter是最方便的
    • 如果文本文件使用的编码表不是默认的,可以使用转换流(InputStreamReaderOutputStreamWriter),它们可以指定编码表,它们的构造参数需要字节流,以借助它们进行编码转换
  • 缓冲流在字符流和字节流都存在,目的在于提高读写效率
  • 在输出流中提供了打印流,方便程序调用

File类

文件和目录路径名的抽象表示形式,该类具有平台无关性。

路径

  • windows下文件(夹)名不区分大小写,linux下则区分。

绝对路径与相对路径

绝对路径

在系统中具有唯一性,如c:\\windows\\system32http://www.baidu.com

相对路径

表示的是路径之间的相对关系

  • 父目录,唯一
  • 子目录,可以不唯一

静态字段

  • static String pathSeparator,与系统有关的路径分隔符(整个目录的分割,表示整个目录结束,比如windows下为;,在linux下为:
  • static Char separator,与系统相关的名称分隔符(单个目录名称的分隔符,表示单个目录名称结束,比如在windows下为\,在linux下为/

构造方法

构造方法本身不判断路径是否存在

声明 解释
File(String pathname) pathname表示的是文件或文件夹的路径,将其封装成File对象
File(String parent, String child) 将父路径和子路径组装起来得到整个路径,并将其转为File对象,优点:可以单独操作父路径或子路径
File(File parent, String child) 基于父File对象的路径组装子路径,并转为File对象,有点:父路径可以直接调用File的方法

创建与删除

方法 解释
boolean createNewFile() 创建文件(路径在构造方法参数中),若已存在不再创建,返回false
boolean mkdir() 创建单层文件夹,若已存在不再创建,返回false
boolean mkdirs() 创建(可多层)文件夹,若已存在不再创建,返回false
boolean delete() 删除文件/文件夹,返回值为删除是否成功;删除的文件不进入回收站

获取功能

方法 解释
String getName() 返回路径表示的最后的文件或者文件夹名,不考虑是否真实存在
String getPath() 返回路径字符串,相当于toString()
long length() 返回路径中表示的文件的字节数,文件夹的话总是0
String getAbsolutePath() 返回绝对路径字符串
File getAbsoluteFile() 返回绝对路径形式的File对象(即使最初的File使用相对路径产生的)
String getParent() 返回父路径的字符串
File getParentFile() 返回父路径的File对象

判断功能

方法 解释
boolean exists() 返回File对象封装的路径是否存在
boolean isDirectory() File对象封装的路径是不是目录
boolean isFiles() File对象封装的路径是不是文件

list和listFile获取功能

方法 解释
String[] list() 获取File中封装的路径中的所有文件夹和文件名数组,对文件调用总是返回null
File[] listFile() 获取File中封装的路径中的的所有文件与目录的File对象

文件过滤器

使用listFile的重载形式

  • File[] listFile(FileFilter filter) ,返回满足指定条件的文件夹与文件数组,其中的接口FileFilter需要自己实现如下方法
    • boolean accept(File file)
  • File[] listFile(FileNameFilter nameFilter),返回满足指定条件的文件夹与文件数组,其中的接口FileFilter需要自己实现如下方法
    • boolean accept(File dir, String name),其中的dir实际是进行文件搜索的文件夹

递归

方法定义中调用方法本身的现象

直接递归

public void methodA(){
    methodA();
}

间接递归

public void metohdB(){
    methodC();
}
public void methodC(){
    methodB();
}

递归注意实现

  • 要有出口,否则就是死递归
  • 次数不能太多,否则就内存溢出

字节流

IO输入输出以程序为参考点,从硬盘、网络、文件等获取数据到程序中使用为输入,反之为输出。

OutputStream抽象类

所有字节输出流的父类。

常用方法

方法 解释
void write(int b) 写入一个字节
void write(byte[] bs) 写入字节数组
void write(byte[] bs, int start, int len) 写入字节数组给定起始位置和个数的字节
void close() 关闭字节流并释放相关资源
void flush() 强制写出

FileOutputStream类

OutputStream的一个子类。

构造方法

  • FileOutputStream(File file)
  • FileOutputStream(String name)
  • FileOutputStream(File file, boolean append)
  • FileOutputStream(String name, boolean append)

构造器需要传入输出目的地,如果没有可以自动创建,如果已存在,当单参数时会自动覆盖;两个参数的构造方法的第二个参数为true时可以以添加的方式输出数据。

异常处理参考写法

File file = new File("a.txt");
OutputStream is = null;
try {
    is = new FileOutputStream(file, true);
    is.write(1);
}catch(Exception ex) {
    ex.printStackTrace();
    throw new RuntimeException("fail to write");
}finally {
    if(is != null) {
        try {
            is.close();
        }catch(IOException ioEx) {
            throw new RuntimeException("fail to close file")
        }
    }
}

InputStream抽象类

常用方法

方法 解释
abstract int read() 读取一个字节,已到达文件末尾返回-1
int read(byte[] bs) 读取一定量字节数组存到缓存数组中,返回读取到的长度,到了文件末尾返回-1

FileInputStream类

OutputStream相对,是InputStream的子类

字符流

由于某些编码表中用多字节存储单个字符,因此使用字节码容易出现问题,为此可以使用字符流。

Writer抽象类

所有字符输出流的超类,只能用于写文本文件。使用时注意使用flush()刷新。

方法 解释
void write(int c) 写单个字符
void write(char[] b, int off, int len) 写字符数组
void write(String str) 写字符串
void write(String str, int off, int len) 写字符串特定部分

OutputStreamWriter

将字符流转换成字节流,可以控制编码表

  • OutputStreamWriter(OutputStream os)
  • OutputStreamWriter(OutputStream os, String charset)

FileWriter类

OutputStreamWriter的直接子类,它直接输出到文件而不是字节流,常用构造方法:

  • FileWriter(File file[, boolean append])
  • FileWriter(String name[, boolean append])

Reader抽象类

所有字符输入流的超类,只能用于读文本文件。

方法 解释
int read() 读取单字符
int read(char[] cbuf) 读取字节数组

InputStreamReader类

将字节流转换成字符流,可以控制编码表。构造方法参考OuputStreamWriter

FileReader类

InputStreamReader的直接子类,构造方法类似FileWriter

缓冲流

BufferedInputStream类

构造方法:BufferedInputStream(InputStream is)

BufferedOutputStream类

构造方法:BufferedOutputStream(OutputStream is)

BufferedReader类

构造方法:BufferedReader(Reader r)

特有方法:String readLine(),读取一个行

BufferedWriter类

构造方法;BufferedWriter(Writer r)

特有方法:void newLine(),换行,平台无关

Properties类

基本使用

HashTable的子类,有Map的相应功能,但有自己的一些特有方法:

方法 解释
String getProperty(String key) 获取键对应的值
Object setProperty(String key, String value) 设定键对应的值
Set<String> stringPropertyNames() 获取键的集合

结合IO流使用

可以用利用IO流,实现文件中的键值对和集合中的键值对的相互存取

方法 解释
void load(InputStream is) 从字节输入流读入数据进Properties集合
void load(Reader r) 从字符输入流读入数据进Properties集合
void store(OutputStream os, String comments) Properties集合键值对写入字节输出流
void store(Writer w, String comments) Properties集合键值对写入字符输出流

对象序列化

  • 能被序列化的对象的列需要实现Serializable接口,这是一个标记接口,不需要实现具体的方法
  • 实现Serializable接口的类,自动获得一个序列版本号serialVersionUID,源码修改后会自动改变,可以人为强制固定,如private static final long serialVersionUID = 1L;
  • 静态成员不能被序列化
  • transient标记的成员不被序列化

存储

  • ObjectOutputStream(InputStream is),创建对象序列化输出流
  • void writeObject(Object o),将对象写入流中

读取

  • ObjectOutputStream(InputStream is),创建对象序列化输入流
  • Object readObject(Object o),从流中读取对象

打印流

  • PrintStreamPrintWriter,后者更灵活常用
  • 不负责输入流,为其他输出流添加了功能
  • 满足以下两个条件可以启用自动刷新
    • 数据目的是流对象
    • 调用printlnprintfformat之一的方法
  • 总是不会抛出IOException,但可能抛其他异常

构造方法

  • PrintStream(File f)
  • PrintStream(String filename)
  • PrintStream(OuputStream os)
  • PrintWriter(File f)
  • PrintWriter(String filename)
  • PrintWriter(OutputSteam os)
  • PrintWriter(Writer w)

实例方法

  • void print(String str): 输出任意类型的数据,
  • void println(String str): 输出任意类型的数据,自动写入换行操作

其中的参数有多种重载,可以是数字、字符、对象等。

commons-io工具类

这是一个外来工具包,JDK本身不自带;提供了操作文件夹和文件的方法;更多详情可查看官网在线API文档

FilenameUtils

  • static String getExtension(String path),获取文件的扩展名
  • static String getName(),获取文件名
  • static boolean isExtension(String fileName,String ext),判断fileName是否是ext后缀名

FileUtils

  • static readFileToString(File file),读取文件内容,并返回一个String
  • static writeStringToFile(File file,String content),将内容content写入到file中
  • static copyFile(File srcFile,File destFile),文件复制
  • static copyDirectoryToDirectory(File srcDir,File destDir),文件夹复制

(本文完)

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。