IO-字符流&其它流
**字节流:**适合复制文件等,不适合读写文本文件
**字符流:**适合读写文本文件内容
IO流体系
字符流
FileReader(文件字符输入流)
作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中来。
构造器 | 说明 |
---|---|
public FileReader(File file) | 创建字符输入流管道与源文件接通 |
public FileReader(String pathname) | 创建字符输入流管道与源文件接通 |
方法名称 | 说明 |
---|---|
public int read() | 每次读取一个字符返回,如果发现没有数据可读会返回-1. |
public int read(char[] buffer) | 每次用一个字符数组去读取数据,返回字符数组读取了多少个字符,如果发现没有数据可读会返回-1. |
- 文件字符输入流,每次读取一个字符的api是哪个?
方法名称 | 说明 |
---|---|
public int read() | 每次读取一个字符返回,如果字节已经没有可读的返回-1 |
-
字符流的好处。每次读取一个字符存在什么问题?
- 读取中文字符不会出现乱码(如果代码文件编码一致)
- 性能较慢
-
文件字符输入流,每次读取一个字符数组的api是哪个?
方法名称 | 说明 |
---|---|
public int read(char[] buffer) | 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1 |
- 每次读取一个字符数组的优势?
- 读取的性能得到了提升
- 读取中文字符输出不会乱码。
FileWriter(文件字符输出流)
**作用:**以内存为基准,把内存中的数据以字符的形式写出到文件中去。
构造器 | 说明 |
---|---|
public FileWriter(File file) | 创建字节输出流管道与源文件对象接通 |
public FileWriter(String filepath) | 创建字节输出流管道与源文件路径接通 |
public FileWriter(File file,boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
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) | 写一个字符串的一部分 |
注意:
- 字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效
方法名称 | 说明 |
---|---|
public void flush() throws IOException | 刷新流,就是将内存中缓存的数据立即写到文件中去生效! |
public void close() throws IOException | 关闭流的操作,包含了刷新! |
-
字符输出流如何实现写出去的数据能换行
- fw.write(“\r\n”)
-
字符输出流如何实现写出去的数据能换行
- flush()刷新数据
- close()方法是关闭流,关闭包含刷新,关闭后流不可以继续使用了。
- 字节流、字符流的使用场景总结?
- 字节流适合做一切文件数据的拷贝(音视频,文本)
- 字节流不适合读取中文内容输出
- 字符流适合做文本文件的操作(读,写)
缓冲流
IO流体系
对原始流进行包装,以提高原始流读写数据的性能
字节缓冲流
- 作用
- 提高字节流读写数据的性能
- 字节缓冲输入流自带了8KB缓冲池;字节缓冲输出流也自带了8KB缓冲池。
构造器 | 说明 |
---|---|
public BufferedInputStream(InputStream is) | 把低级的字节输入流包装成一个高级的缓冲字节输入流,从而提高读数据的性能 |
public BufferedOutputStream(OutputStream os) | 把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
总结
-
字节缓冲流有几种?
- 字节缓冲输入流:BufferedInputStream
- 字节缓冲输出流:BufferedOutputStream
-
字节缓冲流为什么提高了字节流读写数据的性能?
- 字节缓冲流自带8KB缓冲区
- 可以提高原始字节流、字符流读写数据的性能
-
功能上并无很大变化,性能提升了。
字符缓冲流
自带8K的字符缓冲池,可以提高字符输入流读取字符数据的性能
BufferedReader(字符缓冲输入流)
方法 | 说明 |
---|---|
public BufferedReader(Reader r) | 把低级的字符输入流包装成字符缓冲输入流管道,从而提高字符输入流读字符数据的性能 |
public String readLine() | 读取一行数据返回,如果没有数据可读了,会返回null |
BufferedWriter(字符缓冲输出流)
方法 | 说明 |
---|---|
public BufferedWriter(Writer r) | 把低级的字符输出流包装成一个高级的缓冲字符输出流,从而提高字符输出流写数据的性能 |
public void newLine() | 换行 |
总结
-
字符缓冲流有几种,好处是什么?
- public BufferedReader(Reader r)
- public BufferedWriter(Writer w)
- 字符缓冲流自带8K缓冲区,可以提高原始字符流读写数据的性能
-
两种字符缓冲流新增了哪些方法?
- BufferedReader,多了readLine()按照行读取的功能
- BufferedWriter,多了newLine()换行的功能
- 推荐使用哪种方式提高字节流读写数据的性能?
- 建议使用字节缓冲输入流、字节缓冲输出流,结合字节数组的方式,目前来看是性能最优的组合。
转换流
字符流直接读取文本内容
- 必须文件和代码编码一致才不会乱码
- 如果文件和代码编码不一致,读取将出现乱码。
字符输入转换流
字符输入转换流InputStreamReader作用:
- 可以解决字符流读取不同编码乱码的问题
public InputStreamReader(InputStream is,String charset):
可以指定编码把原始字节流转换成字符流,如此字符流中的字符不乱码。
字符输出转换流
字符输出转换流OutputStreamWriter的作用?
public OutputStreamWriter(OutputStream os,String charset)
可以指定编码把字节输出流转换成字符输出流,从而可以指定写出去的字符编码!
打印流
IO流体系
PrintStream/PrintWriter(打印流)
作用:打印流可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去。
构造器 | 说明 |
---|---|
public PrintStream(OutputStream/File/String) | 打印流直接通向字节输出流/文件/文件路径 |
public PrintWriter(OutputStream/Writer/File/String) | 打印流直接通向字符输出流/文件/文件路径 |
方法 | 说明 |
---|---|
public void println(Xxx xx) | 打印任意类型的数据出去 |
public void write(int/byte[]/byte[]一部分) | 可以支持写字节数据出去(PrintStream) |
public void write(int/String/char[]/…) | 可以支持写字符数据出去(PrintWriter) |
打印流 数量 特点 重定向
打印流有几种?各有什么特点?
- 打印流一般是指:PrintStream,PrintWriter两个类。
- 打印数据的功能上是一模一样的:都是使用方便,性能高效(核心优势)
- PrintStream继承自字节输出流OutputStream,支持写字节
- PrintWrite继承自字符输出流Writer,支持写字符
输出语句重定向
- 属于打印流的一种应用,可以把输出语句的打印位置改到文件。
PrintStream ps = new PrintStream("文件地址")System.setOut(ps);
数据流
IO流体系
DataOutputStream(数据输出流)
允许把数据和其类型一并写出去。
构造器 | 说明 |
---|---|
public DataOutputStream(OutputStream out) | 创建新数据输出流包装基础的字节输出流 |
方法 | 说明 |
---|---|
public final void writeByte(int v) throws IOException | 将byte类型的数据写入基础的字节输出流 |
public final void writeInt(int v) throws IOException | 将int类型的数据写入基础的字节输出流 |
public final void writeDouble(Double v) throws IOException | 将double类型的数据写入基础的字节输出流 |
public final void writeUTF(String str) throws IOException | 将字符串数据以UTF-8编码成字节写入基础的字节输出流 |
public void write(int/byte[]/byte[]一部分) | 支持写字节数据出去 |
DataInputStream(数据输入流)
用于读取数据输出流写出去的数据。
构造器 | 说明 |
---|---|
public DataInputStream(InputStream is) | 创建新数据输入流包装基础的字节输入流 |
方法 | 说明 |
---|---|
Public final byte readByte() throws IOException | 读取字节数据返回 |
public final int readInt() throws IOException | 读取int类型的数据返回 |
public final double readDouble() throws IOException | 读取double类型的数据返回 |
public final String readUTF() throws IOException | 读取字符串数(UTF-8)据返回 |
public int readInt()/read(byte[]) | 支持读字节数据进来 |
序列化对象
对象序列化:把Java对象写入到文件中去
对象反序列化:把文件里的Java对象读出来
IO流体系
ObjectOutputStream(对象字节输出流)
可以把Java对象进行序列化:把Java对象存入到文件中去。
方法 | 说明 |
---|---|
public ObjectOutputStream(OutputStream out) | 创建对象字节输出流,包装基础的字节输出流 |
public final void writeObject(Object o) throws IOException | 把对象写出去 |
ObjectInputStream(对象字节输入流)
可以把Java对象进行反序列化:把存储在文件中的Java对象读入到内存中来。
方法 | 说明 |
---|---|
public ObjectInputStream(InputStream is) | 创建对象字节输入流,包装基础的字节输入流 |
public final Object readObject() | 把存储在文件中的Java对象读出来 |
注意:
- 对象如果要参与序列化,必须实现序列化接口(java.io.Serializable)
提问:
- 如果要一次序列化多个对象,怎么办?
- 用一个ArrayList集合存储多个对象,然后直接对集合进行序列化即可(注意:ArrayList集合已经实现了序列化接口!)
总结
-
对象序列化的含义
- 把对象数据存入到文件中去。
- 对象字节输出流ObjectOutputStram
- public void writeObject(Object obj)
- 对象必须实现序列化接口
-
对象反序列化含义
-
把磁盘中的对象数据恢复到内存的Java对象中。
- 把对象数据存入到文件中去
- 对象字节输入流ObjectInputStram
- public Object readObject()
资源释放的方式
try-catch-finally
try {
...
...
} catch (IOException e) {
e.printStackTrace();
}finally{ }
finally代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止。
作用:一般用于在程序执行完成后进行资源的释放操作(专业级做法)。
try-with-resource
try-with-resource(JDK7开始提供)
try(定义资源1;定义资源2;…){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
该方式声明的资源使用完毕后,会自动调用其close()方法,完成释放!
自动释放资源、代码简洁自动释放资源、代码简洁
() 中只能放置资源,否则报错
什么是资源呢?
资源一般指的是最终实现了AutoCloseable接口。
public abstract class InputStream implements Closeable{ }
public abstract class OutputStream implements Closeable, Flushable { }
public interface Closeable extends AutoCloseable { }
IO框架
什么是(IO)框架
框架
- 解决某类问题,编写的一套类、接口等,可以理解成一个半成品。
- 好处:在框架的基础上开发,可以得到优秀的软件架构,并能提高开发效率
- 框架的形式:一般是把类、接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去。
IO框架
- 封装了Java提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等
- 使用commons-io简化io流读写
Commons-io
Commons-io是apache开源基金组织提供的一组有关IO操作的小框架,目的是提高IO流的开发效率。
FileUtils类提供的部分方法展示 | 说明 |
---|---|
public static void copyFile(File srcFile, File destFile) | 复制文件 |
public static void copyDirectory(File srcDir, File destDir) | 复制文件夹 |
public static void deleteDirectory(File directory) | 删除文件夹 |
public static String readFileToString(File file, String encoding) | 读数据 |
public static void writeStringToFile(File file, String data, String charname, boolean append) | 写数据 |
IOUtils类提供的部分方法展示 | 说明 |
---|---|
public static int copy(InputStream inputStream, OutputStream outputStream) | 复制文件 |
public static int copy(Reader reader, Writer writer) | 复制文件 |
public static void write(String data, OutputStream output, String charsetName) | 写数据 |