一、File类概述
1.目前在内存中存储的数据是用来处理、修改、运算的,不能长久保存
2..File类在包java.io.File下、代表操作系统的文件对象(文件、文件夹)
3.File类用途:定位文件,获取文件本身的信息、删除文件、创建文件(文件夹)等,但是不能读写文件内容(IO流)
4.File类构建对象的方式:
File file = new File(“文件/文件/绝对路径/相对路径”);
注意:(1)File对象可以定位文件和文件夹
(2)File封装的对象仅仅是一个路径名,这个路径可以是存在的,也可以是不存在的
5.绝对路径和相对路径:
绝对路径是带盘符的,依赖当前系统。 相对路径是不带盘符的,默认相对到工程下开始寻找文件。
二、File类的常用API
1.判断文件类型、获取文件信息:
方法名称 | 说明 |
public boolean isDirectory() | 测试此抽象路径名表示的File是否为文件夹 |
public boolean isFile() | 测试此抽象路径名表示的File是否为文件 |
public boolean exists() | 测试此抽象路径名表示的File是否存在 |
public String getAbsolutePath() | 返回此抽象路径名的绝对路径名字符串 |
public String getPath() | 将此抽象路径名转换为路径名字符串 |
public String getName() | 返回由此抽象路径名表示的文件或文件夹的名称 |
public long lastModified() | 返回文件最后修改的时间毫秒值 |
2.File类创建文件的功能:
方法名称 | 说明 |
public boolean createNewFile() | 创建一个新的空的文件 |
public boolean mkdir() | 只能创建一级文件夹 |
public boolean mkdirs() | 可以创建多级文件夹 |
3.File类删除文件功能
方法名称 | 说明 |
public boolean delete() | 删除由此抽象路径名表示的文件或空文件夹 |
注意:(1)delete方法默认只能删除文件和空文件夹,默认不能删除非空文件夹
(2)delete方法直接删除不走回收站
4.File类的遍历功能
方法名称 | 说明 |
public String[] list() | 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。 |
public File[] listFiles()(常用) | 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点) |
listFiles方法注意事项:
(1)当调用者不存在时,返回null
(2)当调用者是一个文件时,返回null
(3)当调用者是一个空文件夹时,返回一个长度为0的数组
(4)当调用者是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
(5)当调用者是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏内容
(6)当调用者是一个需要权限才能进入的文件夹时,返回null
三、字符集
计算机底层不可以直接存储字符的,计算机中底层只能存储二进制的(0、1),但是二进制是可以转换成十进制的,所以计算机底层可以表示十进制编号。计算机可以给人类字符进行编号存储,这套编号规则就是字符集。
1.常见的字符集
- ASCII字符集:
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码):包括了数字、英文、符号,ASCII使用1个字节存储一个字符,一个字节是8位,总共可以表示128个字符信息,对于英文,数字来说是够用的。
- GBK字符集:
window系统默认的码表。兼容ASCII码表,也包含了几万个汉字,并支持繁体汉字以及部分日韩文字。GBK是中国的码表,一个中文以两个字节的形式存储,一个英文以一个字节的形式存储,但不包含世界上所有国家的文字。
- Unicode码表:
unicode(又称统一码、万国码、单一码)是计算机科学领域里的一项业界字符编码标准。 容纳世界上大多数国家的所有常见文字和符号。由于Unicode会先通过UTF-8,UTF-16,以及 UTF-32的编码成二进制后再存储到计算机,其中最为常见的就是UTF-8。
注意:(1)Unicode是万国码,以UTF-8编码后一个中文一般以三个字节的形式存储。
(2)UTF-8也要兼容ASCII编码表。
(3)编码前和编码后的字符集需要一致,否则会出现中文乱码,英文和数字在任何国家的编码中都不会乱码(以ASCII字符集为基础)。
2.String编码
方法名称 | 说明 |
byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 |
byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 |
3.String解码
构造器 | 说明 |
String(byte[] bytes) | 通过使用平台的默认字符集解码指定的字节数组来构造新的 String |
String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来构造新的 String |
四、IO流概述
IO流也称为输入、输出流,就是用来读写数据的。I表示intput,是数据从硬盘文件读入到内存的过程,称之输入,负责读。O表示output,是内存程序的数据从内存到写出到硬盘文件的过程,称之输出,负责写。输入流:读数据到内存;输出流:写数据到磁盘。
字节流、字符流如何选择使用
- 字节流适合做一切文件数据的拷贝(音视频,文本)
- 字节流不适合读取中文内容输出
- 字符流适合做文本文件的操作(读,写)
五、字节流的使用
1.文件字节输入流(一个字节/字节组):
(1) 文件字节输入流:FileInputStream
(2) 建立连通管道:
构造器 | 说明 |
public FileInputStream(File file) | 创建字节输入流管道与源文件对象接通 |
public FileInputStream(String pathname) | 创建字节输入流管道与源文件路径接通 |
(3)读取字节/字节数组返回
方法名称 | 说明 |
public int read() | 每次读取一个字节返回,如果字节已经没有可读的返回-1 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
(4)每次读取一个字节存在的问题:
性能较慢,读取中文字符输出无法避免乱码问题。
(5)每次读取一个字节数组存在的问题
读取的性能得到了提升,读取中文字符输出无法避免乱码问题。
2.文件字节输入流(一次读完全部字节)
(1)优势:读取中文内容输出不乱码
(2)缺点:如果文件过大,字节数组可能引起内存溢出
(3)定义方式:
方式一:自己定义一个字节数组与文件的大小一样大,然后使用读取字节数组的方法,一次性读取完成。
方法名称 | 说明 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
方式二: 官方为字节输入流InputStream提供了如下API可以直接把文件的全部数据读取到一个字节数组中(JDK9之后出现)
方法名称 | 说明 |
public byte[] readAllBytes() throws IOException | 直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回 |
3. 文件字节输出流(写字节数据到文件)
(1)文件字节输出流:FileOutputStream
(2)作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去。
(3)创建输出流的管道:(追加:append = true)
构造器 | 说明 |
public FileOutputStream(File file) | 创建字节输出流管道与源文件对象接通 |
public FileOutputStream(File file,boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
public FileOutputStream(String filepath) | 创建字节输出流管道与源文件路径接通 |
public FileOutputStream(String filepath,boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
(4) 文件字节输出流(FileOutputStream)写数据出去的API
方法名称 | 说明 |
public void write(int a) | 写一个字节出去 |
public void write(byte[] buffer) | 写一个字节数组出去 |
public void write(byte[] buffer , int pos , int len) | 写一个字节数组的一部分出去。 |
(5) 流的关闭与刷新
方法 | 说明 |
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
(6)字节输出流如何实现写出去的数据能换行:os.write(“\r\n”.getBytes())
(7)注意:文件不存在时,可以自动生成;写完数据一定要刷新将缓存在内存中的数据放入文件中;关闭流自带刷新方法;
4.文件拷贝
任何文件的底层都是字节,拷贝是一字不漏的转移字节,只要前后文件格式、编码一致没有任何问题即可,所以字节流适合做一切文件数据的拷贝。
六、资源释放的方式
1.try-catch-finally (手动释放资源)
(1)finally:在异常处理时提供finally块来执行所有清除操作,比如说IO流中的释放资源
(2)特点:被finally控制的语句最终一定会执行,除非JVM退出
(3)try-catch-finally格式
InputStream is = null ;
OutputStream os = null;
try{
//执行的代码块,可能出现异常的代码;
}catch (Exception e){
//异常处理
e.printStackTrace();
} finally {
// 执行所有关闭资源释放操作!
}
2. try-with-resource (自动释放资源)
(1)JDK7改进方案:(常用)在try中定义流对象,使用完自动释放
(2)JDK9改进方案:(不建议使用,必须初始化)
注意:JDK 7 以及 JDK 9的try()中只能放置资源对象,否则报错,资源都是实现了Closeable/AutoCloseable接口的类对象
七、字符流的使用
使用字符流的好处:字节流读取中文输出会乱码或者内存溢出,所以读取中文输出字符流更合适,最小单位是按照单个字符读取的。
1.文件字符输入流:一次读取一个字符/字符数组
(1)文件字符输入流:Reader
(2)作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去。
(3)建立输入流的管道:
构造器 | 说明 |
public FileReader(File file) | 创建字符输入流管道与源文件对象接通 |
public FileReader(String pathname) | 创建字符输入流管道与源文件路径接通 |
(4) 读取字符/字符数组返回
方法名称 | 说明 |
public int read() | 每次读取一个字符返回,如果字符已经没有可读的返回-1 |
public int read(char[] buffer) | 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1 |
注意:在使用祖父数组读取数据的时候,一定要定义返回的字符数,防止最后一桶水装不满,造成乱码问题
(5)字符流的好处:读取中文字符不会出现乱码(如果代码文件编码一致)
每次读取一个字符存在的问题:性能较慢
每次读取一个字符数组的优势:读取的性能得到了提升
2.文件字符输出流:(写字符数据到文件)
(1)文件字符输出流:FileWriter
(2)作用:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件中去。
(3)创建输出流的管道:(追加:append = true)
构造器 | 说明 |
public FileWriter(File file) | 创建字符输出流管道与源文件对象接通 |
public FileWriter(File file,boolean append) | 创建字符输出流管道与源文件对象接通,可追加数据 |
public FileWriter(String filepath) | 创建字符输出流管道与源文件路径接通 |
public FileWriter(String filepath,boolean append) | 创建字符输出流管道与源文件路径接通,可追加数据 |
(4)文件字符输出流(FileWriter)写数据出去的API
方法名称 | 说明 |
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) | 写一个字符 |
(5) 流的关闭与刷新
方法 | 说明 |
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
(6) 字符输出流如何实现写出去的数据能换行:fw.write(“\r\n”)
八、缓冲流
1.缓冲流概述
(1)缓冲流也称为高效流、或者高级流
(2)作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能(鸟枪换炮)
(3)缓冲流的种类
- 字节缓冲输入流: BufferedInputStream
- 字节缓冲输出流:BufferedOutputStream
- 字符缓冲输入流:BufferedReader
- 字符缓冲输出流:BufferedWriter
2.字节缓冲流
(1)字节缓冲流性能优化原理:
字节缓冲输入流和输出流自带了8KB缓冲池,所以直接从缓冲池读取数据,所以性能较好;字节缓冲输出流中,数据就直接写入到缓冲池中去,写数据性能极高了。
(2)字节缓冲流
字节缓冲输入流和输出流,只是提高了流de读取数据的性能,读写功能上并无变化。
构造器 | 说明 |
public BufferedInputStream(InputStream is) | 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能 |
public BufferedOutputStream(OutputStream os) | 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
注意:使用缓冲流时,必须先创建低级流管道
3.字节缓冲流的性能分析
测试方式:可以分别使用低级字节流和高级字节缓冲流拷贝大视频,记录耗时。
结果:使用字节缓冲输入流、字节缓冲输出流,结合字节数组的方式,目前是性能最优的组合
4.字符缓冲流
(1)字符缓冲输入流:BufferedReader
(2)作用:提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。
(3)字符缓冲流
构造器 | 说明 |
public BufferedWriter(Writer w) | 可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能 |
(4) 字符缓冲输出流新增功能
方法 | 说明 |
public void newLine() | 换行操作 |
九、转换流
1.出现原因:
如果代码编码和文件编码不一致,直接使用字符流直接读取会乱码,只有文件编码和读取的编码必须一致才不会乱码。
2.字符输入转换流
(1)字符输入转换流:InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流。
构造器 | 说明 |
public InputStreamReader(InputStream is) | 可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用与默认的FileReader一样。 |
public InputStreamReader(InputStream is ,String charset) | 可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中字符就不乱码了(重点) charset(编码) |
(2)字符输入转换流InputStreamReader作用:可以解决字符流读取不同编码乱码的问题
3.字符输出转换流
(1)字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。
构造器 | 说明 |
public OutputStreamWriter(OutputStream os) | 可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用。 |
public OutputStreamWriter(OutputStream os,String charset) | 可以把原始的字节输出流按照指定编码转换成字符输出流(重点) |
(2)字符输出转换流OutputStreamWriter的作用:
可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码!
十、序列化(反序列化)对象
1.对象序列化:
(1)作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化。
(2)序列化对象的要求: 对象必须实现序列化接口(对象实体必须实现Serializable接口)
(3)对象序列化:
构造器 | 说明 |
public ObjectOutputStream(OutputStream out) | 把低级字节输出流包装成高级的对象字节输出流 |
(4) ObjectOutputStream序列化方法
方法名称 | 说明 |
public final void writeObject(Object obj) | 把对象写出去到对象序列化流的文件中去 |
(5)代码示例:
public static void main(String[] args) throws IOException {
//1、创建学生对象
Student student = new Student("范","fanjingxuan","123456789",20);
// 2、对象序刚化:使用对象字节输出流包装字节输出流管道
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\JavaDaima\\序列化.txt"));
// 3.直接调用序列化的方法
oos.writeObject(student);
// 4、释放资源
oos.close();
}
2.对象反序列化:
(1)作用:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化。
(2)对象反序列化:
构造器 | 说明 |
public ObjectInputStream(InputStream out) | 把低级字节输如流包装成高级的对象字节输入流 |
(3)ObjectInputStream序列化方法
方法名称 | 说明 |
public Object readObject() | 把存储到磁盘文件中去的对象数据恢复成内存中的对象返回 |
(4) 反序列化代码示例
public static void main(String[] args) throws Exception{
// 1.创建对象字节输入流管道包装低级的字节输入流管道
ObjectInputStream is = new ObjectInputStream(new FileInputStream("E:\\JavaDaima\\序列化.txt"));
// 2.调用对象字节输入流的反序列化方法 readObject
Student student = (Student) is.readObject();
//3.输出对象
System.out.println(student);
}
(5)如果对象中的字段不参与序列化,则使用 transient 修饰成员变量,
//passWord 成员变量不参与序列化
private transient String passWord;
(6)声明序列化版本号:当序列号的版本号与反序列化的版本号一致时才不会出错
//声明序列化的版本号
private static final long serialversionUIO = 1;
十一、打印流
1.打印流
(1)打印流一般是指:PrintStream,PrintWriter两个类。
(2)作用:打印流可以实现方便、高效的打印数据到文件中去。可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。
(3)PrintStream(打印字节流)
构造器 | 说明 |
public PrintStream(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintStream(File f) | 打印流直接通向文件对象 |
public PrintStream(String filepath) | 打印流直接通向文件路径 |
(4)PrintWriter(打印字符流)
构造器 | 说明 |
public PrintWriter(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintWriter (Writer w) | 打印流直接通向字符输出流管道 |
public PrintWriter (File f) | 打印流直接通向文件对象 |
public PrintWriter (String filepath) | 打印流直接通向文件路径 |
(5)打印数据
方法 | 说明 |
public void print(Xxx xx) | 打印任意类型的数据出去 |
(6)PrintStream和PrintWriter的区别:
- 打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)(内部基于缓冲期)
- PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。(字节)
- PrintWriter继承自字符输出流Writer,支持写字符数据出去。(字符)
- 如果追加数据,则在低级管道流中追加(true)
2.输出语句的重定向
属于打印流的一种应用,可以把输出语句的打印位置改到文件。
PrintStream ps = new PrintStream("文件地址")
System.setOut(ps);
十二、Properties
1.Properties简介
(1)Properties实质:其实就是一个Map集合
(2)Properties核心作用:
- Properties代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
- 属性文件:后缀是.properties结尾的文件,里面的内容都是 key=value,后续做系统配置信息的。
2.Properties的API (和IO流结合的方法):
构造器 | 说明 |
void load(InputStream inStream) | 从输入字节流读取属性列表(键和元素对) |
void load(Reader reader) | 从输入字符流读取属性列表(键和元素对) |
void store(OutputStream out, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法的格式写入输出字节流 |
void store(Writer writer, String comments) | 将此属性列表(键和元素对)写入此 Properties表中,以适合使用 load(Reader)方法的格式写入输出字符流 writer:流管道 comments:注释 |
public Object setProperty(String key, String value) | 保存键值对(put) |
public String getProperty(String key) | 使用此属性列表中指定的键搜索属性值 (get) |
public Set<String> stringPropertyNames() | 所有键的名称的集合 (keySet()) |
3. Properties的作用:
- 可以存储Properties属性集的键值对数据到属性文件中去:void store(Writer writer, String comments)
- 可以加载属性文件中的数据到Properties对象中来: void load(Reader reader)
十三、IO框架
1.commons-io概述:
- commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
- commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils
2.FileUtils主要有如下方法:
方法名 | 说明 |
String readFileToString(File file, String encoding) | 读取文件中的数据, 返回字符串 |
void copyFile(File srcFile, File destFile) srcFile:原 destFile:新 | 复制文件。 |
void copyDirectoryToDirectory(File srcDir, File destDir) | 复制文件夹。 |