IO概述
- 当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)
Output
操作。 - 当把持久设备上的数据读取到内存中的这个动作称为输入(读)
Input
操作。 - 因此我们把这种输入和输出动作称为
IO
操作。
常用接口与类
继承树
- File类
- 字节流
- OutputStream抽象类
- FileOutputStream类
- ObjectOutputStream类
- …
- BufferedOutputStream类(缓冲流)
- …
- InputStream抽象类
- FileInputStream类
- ObjectInputStream类
- …
- BufferedInputStream类(缓冲流)
- …
- OutputStream抽象类
- 字符流
- Writer抽象类
- BufferedWriter类(缓冲流)
- OutputStreamWriter类(转换流)
- FileWriter类
- …
- Reader抽象类
- BufferedReader类
- InputStreamReader类(转换流)
- FileReader类(缓冲流)
- …
- Writer抽象类
图示
总结
- 文件的通用读写方式是字节流
- 字符流(
Reader
和Writer
)专门用于文本文件的读写(因为非文本文件中没有字符的概念)- 如果确定文本文件是采用的默认编码表,那么直接使用
FileReader
和FileWriter
是最方便的 - 如果文本文件使用的编码表不是默认的,可以使用转换流(
InputStreamReader
和OutputStreamWriter
),它们可以指定编码表,它们的构造参数需要字节流,以借助它们进行编码转换
- 如果确定文本文件是采用的默认编码表,那么直接使用
- 缓冲流在字符流和字节流都存在,目的在于提高读写效率
- 在输出流中提供了打印流,方便程序调用
File类
文件和目录路径名的抽象表示形式,该类具有平台无关性。
路径
windows
下文件(夹)名不区分大小写,linux
下则区分。
绝对路径与相对路径
绝对路径
在系统中具有唯一性,如c:\\windows\\system32
、http://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),从流中读取对象
打印流
PrintStream
和PrintWriter
,后者更灵活常用- 不负责输入流,为其他输出流添加了功能
- 满足以下两个条件可以启用自动刷新
- 数据目的是流对象
- 调用
println
、printf
、format
之一的方法
- 总是不会抛出
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),文件夹复制