框架图:
一、编码介绍
1. 字符集介绍
主要指代一套电脑编码系统,使用码表、编码的方式表示不同字符。
常见的字符集有:
- ASCII字符集
ASCII(American Standard Code for Information Interchange,美国信息交换标准代码):包括了数字、英文、符号。
- GBK字符集
GBK是中国的码表,包含了几万个汉字等字符,兼容ASCII编码,GBK编码中一个中文字符一般以两个字节的形式存储。
- Unicode字符集:
统一码,也叫万国码。是计算机科学领域里的一项业界标准,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。
- UTF-8
UTF-8是Unicode的其中一个使用方式。 UTF是 Unicode Tranformation Format,即把Unicode转做某 种格式的意思,是一种变长的编码,UTF-8编码后一个中文一般以三个字节的形式存储。
1.1 汉字存储和展示过程解析
总结:
1.常见字符集底层字符的编码是什么样的?
-
英文和数字等在任何国家的字符集中都占1个字节
-
GBK字符中一个中文字符占2个字节
-
UTF-8编码中一个中文一般占3个字节
-
UTF-16中,大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。
2.编码前的字符集和解码时的字符集有什么要求?
-
必须一致,否则会出现字符乱码
-
英文和数字不会乱码
2. Java默认编码
JVM内部编码是UTF-16BE(最低地址存放高位字节,编码前会放置FEFF)(JVM中字符串格式为UTF-16)。
String字符串中的字节码是按UTF-16BE编码的。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
...
@Stable
private final byte[] value;
...
}
Java一道面试题:
char 型变量中能不能存贮一个中文汉字,为什么?
答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。
JVM IO流的默认解码方式
- 可以使用Charset.defaultCharset()的值来查看JVM默认的IO编码集,JVM的IO字符集编码取的是操作系统默认的字符集编码。
- Java 中,字符字节转换时,如果不提供字符集,使用JVM默认字符集。例如,字符串和字节数组转换时,字节流和字符流转换时等。
windows操作系统的默认编码可用dos命令chcp查看
如上图,我的活动代码页为936,意思是"中国-简体中文(GBK)"
下表列出了所有支持的代码页及其国家(地区)或者语言:
代码页 国家(地区)或语言
437 美国
708 阿拉伯文(ASMO 708)
720 阿拉伯文(DOS)
850 多语言(拉丁文 I)
852 中欧(DOS) - 斯拉夫语(拉丁文 II)
855 西里尔文(俄语)
857 土耳其语
860 葡萄牙语
861 冰岛语
862 希伯来文(DOS)
863 加拿大 - 法语
865 日耳曼语
866 俄语 - 西里尔文(DOS)
869 现代希腊语
874 泰文(Windows)
932 日文(Shift-JIS)
936 中国 - 简体中文(GB2312)现在是GBK了,GBK是在国家标准GB2312基础上扩容后兼容GB2312的标准。
949 韩文
950 繁体中文(Big5)
1200 Unicode
1201 Unicode (Big-Endian)
1250 中欧(Windows)
1251 西里尔文(Windows)
1252 西欧(Windows)
1253 希腊文(Windows)
1254 土耳其文(Windows)
1255 希伯来文(Windows)
1256 阿拉伯文(Windows)
1257 波罗的海文(Windows)
1258 越南文(Windows)
20866 西里尔文(KOI8-R)
21866 西里尔文(KOI8-U)
28592 中欧(ISO)
28593 拉丁文 3 (ISO)
28594 波罗的海文(ISO)
28595 西里尔文(ISO)
28596 阿拉伯文(ISO)
28597 希腊文(ISO)
28598 希伯来文(ISO-Visual)
38598 希伯来文(ISO-Logical)
50000 用户定义的
50001 自动选择
50220 日文(JIS)
50221 日文(JIS-允许一个字节的片假名)
50222 日文(JIS-允许一个字节的片假名 - SO/SI)
50225 韩文(ISO)
50932 日文(自动选择)
50949 韩文(自动选择)
51932 日文(EUC)
51949 韩文(EUC)
52936 简体中文(HZ)
65000 Unicode (UTF-7)
65001 Unicode (UTF-8)
使用Charset.defaultCharset()的值来查看JVM默认的IO编码集,可以看到默认IO字符集为系统默认的字符集。
JVM默认编码的更改:更改JVM参数 -Dfile.encoding=UTF-8,即在运行java.exe后加上参数。
IDEA在调用Java虚拟机时进行了参数配置,可以在设置中更改该配置,默认配置为UTF-8。
3. String编码
方法名称 | 说明 |
---|---|
byte[] getBytes() | 使用平台的默认字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 |
byte[] getBytes(String charsetName) | 使用指定的字符集将该 String编码为一系列字节,将结果存储到新的字节数组中 |
4. String解码
构造器 | 说明 |
---|---|
String(byte[] bytes) | 通过使用平台的默认字符集解码指定的字节数组来构造新的 String |
String(byte[] bytes, String charsetName) | 通过指定的字符集解码指定的字节数组来构造新的 String |
二、File类介绍
- File类的对象代表操作系统的文件(文件、文件夹),File类在java.io.File包下。
- File类提供了诸如:创建文件对象代表文件,获取文件信息(大小、修改时间)、删除文件、创建文件(文件夹)等功能。
1. File类创建对象
方法名称 | 说明 |
---|---|
public File(String pathname) | 根据文件路径创建文件对象 |
public File(String parent, String child) | 根据父路径名字符串和子路径名字符串创建文件对象 |
public File(File parent, String child) | 根据父路径对应文件对象和子路径名字符串创建文件对象 |
注意
-
File对象可以定位文件和文件夹
-
File封装的对象仅仅是一个路径名,这个路径可以是存在的,也可以是不存在的。
2. 绝对路径和相对路径
- 绝对路径:从盘符开始
File file1 = new File(“D:\\itheima\\a.txt”);
- 相对路径:不带盘符,默认直接到当前工程下的目录寻找文件。
File file3 = new File(“模块名\\a.txt”);
总结:
1、File类的作用?
- 创建对象定位文件,可以删除、获取文件信息等。但是不能读写文件内容。
2、File类构建对象的方式 ?
- File file = new File(“文件/文件夹/绝对路径/相对路径”);
3、绝对路径和相对路径是什么样的?
-
绝对路径是带盘符的。
-
相对路径是不带盘符的,默认到当前工程下寻找文件。
3. File类常用方法
3.1 File类的判断文件类型、获取文件信息功能
方法名称 | 说明 |
---|---|
public boolean isDirectory() | 判断此路径名表示的File是否为文件夹 |
public boolean isFile() | 判断此路径名表示的File是否为文件 |
public boolean exists() | 判断此路径名表示的File是否存在 |
public long length() | 返回文件的大小(字节数量) |
public String getAbsolutePath() | 返回文件的绝对路径 |
public String getPath() | 返回定义文件时使用的路径 |
public String getName() | 返回文件的名称,带后缀 |
public long lastModified() | 返回文件的最后修改时间(时间毫秒值) |
3.2 File类创建文件的功能
方法名称 | 说明 |
---|---|
public boolean createNewFile() | 创建一个新的空的文件 |
public boolean mkdir() | 只能创建一级文件夹 |
public boolean mkdirs() | 可以创建多级文件夹 |
3.3 File类删除文件的功能
方法名称 | 说明 |
---|---|
public boolean delete() | 删除由此抽象路径名表示的文件或空文件夹 |
注意
- delete方法默认只能删除文件和空文件夹,delete方法直接删除不走回收站
总结:
1.创建多级目录使用哪个方法?
- public boolean mkdirs()
2.删除文件需要注意什么?
-
可以删除文件、空文件夹。
-
默认不能删除非空文件夹。
3.4 File类的遍历功能
方法名称 | 说明 |
---|---|
public String[] list() | 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回。 |
public File[] listFiles()(常用) | 获取当前目录下所有的"一级文件对象"到一个文件对象数组中去返回(重点) |
listFiles方法注意事项:
-
当文件不存在时或者代表文件时,返回null
-
当文件对象代表一个空文件夹时,返回一个长度为0的数组
-
当文件对象是一个有内容的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回
-
当文件对象是一个有隐藏文件的文件夹时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
-
当没有权限访问该文件夹时,返回null
总结:
1.如何遍历文件夹下的文件对象,使用哪个API,有什么特点?
-
public File[] listFiles()(常用)。
-
只能遍历当前文件夹对象下的一级文件对象。
三、基本输入输出流
1. 字节流
- 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流称为字节输入流。
- 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流称为字节输出流。
1.1 文件字节输入流:FileInputStream
- 作用:以内存为基准,把磁盘文件中的数据以字节的形式读取到内存中去。
构造器 | 说明 |
---|---|
public FileInputStream(File file) | 创建字节输入流管道与源文件对象接通 |
public FileInputStream(String pathname) | 创建字节输入流管道与源文件路径接通 |
方法名称 | 说明 |
---|---|
public int read() | 每次读取一个字节返回,如果字节已经没有可读的返回-1 |
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
1.2 字节输入流:读取文件的全部字节
方式一
- 自己定义一个字节数组与文件的大小一样大,然后使用读取字节数组的方法,一次性读取完成。
- 使用File类的length()方法,获取文件大小
方法名称 | 说明 |
---|---|
public int read(byte[] buffer) | 每次读取一个字节数组返回,如果字节已经没有可读的返回-1 |
方式二
- 官方为字节输入流InputStream提供了如下API可以直接把文件的全部数据读取到一个字节数组中
方法名称 | 说明 |
---|---|
public byte[] readAllBytes() throws IOException | 直接将当前字节输入流对应的文件对象的字节数据装到一个字节数组返回 |
危害:如果文件过大,字节数组可能引起内存溢出。
1.3 文件字节输出流:FileOutputStream
- 作用:以内存为基准,把内存中的数据以字节的形式写出到磁盘文件中去的流。
构造器 | 说明 |
---|---|
public FileOutputStream(File file) | 创建字节输出流管道与源文件对象接通 |
public FileOutputStream(File file,boolean append) | 创建字节输出流管道与源文件对象接通,可追加数据 |
public FileOutputStream(String filepath) | 创建字节输出流管道与源文件路径接通 |
public FileOutputStream(String filepath,boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
文件字节输出流(FileOutputStream)写数据出去的API
方法名称 | 说明 |
---|---|
public void write(int a) | 写一个字节出去 |
public void write(byte[] buffer) | 写一个字节数组出去 |
public void write(byte[] buffer , int pos , int len) | 写一个字节数组的一部分出去。 |
流的关闭与刷新
方法 | 说明 |
---|---|
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
FileOutputStream的flush方法是从OutputStream继承的,OutputStream 的 flush 方法不执行任何操作。
总结
1.字节输出流写数据的方法有哪些
方法名称 | 说明 |
---|---|
public void write(int a) | 写一个字节出去 |
public void write(byte[] buffer) | 写一个字节数组出去 |
public void write(byte[] buffer , int pos , int len) | 写一个字节数组的一部分出去。 |
2.字节输出流如何实现数据追加
构造器 | 说明 |
---|---|
public FileOutputStream(String filepath,boolean append) | 创建字节输出流管道与源文件路径接通,可追加数据 |
3.字节输出流如何实现写出去的数据能换行
- os.write(“\r\n”.getBytes())
4.如何让写出去的数据能成功生效?
-
flush()刷新数据
-
close()方法是关闭流,关闭包含刷新,关闭后流不可以继续使用了。
1.4 资源释放方式
JDK 7和JDK9中都简化了资源释放操作JDK 7和JDK9中都简化了资源释放操作
基本做法:
手动释放资源
try{
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}finally{
执行所有资源释放操作;
}
JDK7改进方案:
资源用完最终自动释放
try(定义流对象){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
JDK9改进方案:
资源用完最终自动释放
定义输入流对象;
定义输出流对象;
try(输入流对象;输出流对象){
可能出现异常的代码;
}catch(异常类名 变量名){
异常的处理代码;
}
注意
-
JDK 7 以及 JDK 9的()中只能放置资源对象,否则报错
-
什么是资源呢?
-
资源都是实现了Closeable/AutoCloseable接口的类对象
public abstract class InputStream implements Closeable {}
public abstract class OutputStream implements Closeable, Flushable{}
2. 字符流
-
字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流称为字符输入流。
-
字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流称为字符输出流。
以JVM默认的IO编码集方式读入字符,IDEA中默认为UTF-8方式。
如果要读取非JVM默认的IO编码集文件,需要使用字符输入转换流,后面介绍
2.1 文件字符输入流:Reader
- 作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去。
构造器 | 说明 |
---|---|
public FileReader(File file) | 创建字符输入流管道与源文件对象接通 |
public FileReader(String pathname) | 创建字符输入流管道与源文件路径接通 |
方法名称 | 说明 |
---|---|
public int read() | 每次读取一个字符返回,如果字符已经没有可读的返回-1 |
public int read(char[] buffer) | 每次读取一个字符数组,返回读取的字符个数,如果字符已经没有可读的返回-1 |
2.2 文件字符输入流:FileReader
- 作用:以内存为基准,把磁盘文件中的数据以字符的形式读取到内存中去。
方法名称 | 说明 |
---|---|
public int read() | 每次读取一个字符返回,如果字符已经没有可读的返回-1 |
public int read(char[] buffer) | 每次读取一个字符数组,返回读取的字符数,如果字符已经没有可读的返回-1 |
2.3 文件字符输出流:FileWriter
- 作用:以内存为基准,把内存中的数据以字符的形式写出到磁盘文件中去的流。
构造器 | 说明 |
---|---|
public FileWriter(File file) | 创建字符输出流管道与源文件对象接通 |
public FileWriter(File file,boolean append) | 创建字符输出流管道与源文件对象接通,可追加数据 |
public FileWriter(String filepath) | 创建字符输出流管道与源文件路径接通 |
public FileWriter(String filepath,boolean append) | 创建字符输出流管道与源文件路径接通,可追加数据 |
文件字符输出流(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) | 写一个字符串的一部分 |
流的关闭与刷新
方法 | 说明 |
---|---|
flush() | 刷新流,还可以继续写数据 |
close() | 关闭流,释放资源,但是在关闭之前会先刷新流。一旦关闭,就不能再写数据 |
总结
1.字符输出流写数据的方法有哪些
方法名称 | 说明 |
---|---|
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) | 写一个字符串的一部分 |
2.字符输出流如何实现数据追加
构造器 | 说明 |
---|---|
public FileWriter(String filepath,boolean append) | 创建字符输出流管道与源文件路径接通,可追加数据 |
3.字符输出流如何实现写出去的数据能换行
- fw.write(“\r\n”)
4.字符输出流如何实现写出去的数据能换行
-
flush()刷新数据
-
close()方法是关闭流,关闭包含刷新,关闭后流不可以继续使用了。
5.字节流、字符流的使用场景总结?
-
字节流适合做一切文件数据的拷贝(音视频,文本)
-
字节流不适合读取中文内容输出
-
字符流适合做文本文件的操作(读,写)
四、缓冲流概述
- 缓冲流也称为高效流、或者高级流。之前学习的字节流可以称为原始流。
- 作用:缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能
字节缓冲流性能优化原理:
-
字节缓冲输入流自带了8KB缓冲池,以后我们直接从缓冲池读取数据,所以性能较好。
-
字节缓冲输出流自带了8KB缓冲池,数据就直接写入到缓冲池中去,写数据性能极高了。
1. 字节缓冲流
-
字节缓冲输入流:BufferedInputStream,提高字节输入流读取数据的性能。
-
字节缓冲输出流:BufferedOutputStream,提高字节输出流读取数据的性能。
构造器 | 说明 |
---|---|
public BufferedInputStream(InputStream is) | 可以把低级的字节输入流包装成一个高级的缓冲字节输入流管道,从而提高字节输入流读数据的性能 |
public BufferedOutputStream(OutputStream os) | 可以把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能 |
总结
1.缓冲流的作用?
- 缓冲流自带缓冲区、可以提高原始字节流、字符流读写数据的性能
2.缓冲流有几种?
-
字节缓冲流
- 字节缓冲输入流:BufferedInputStream
- 字节缓冲输出流:BufferedOutputStream
-
字符缓冲流
- 字符缓冲输入流:BufferedReader
- 字符缓冲输出流:BufferedWriter
3.字节缓冲流为什么提高了操作数据的性能?
-
字节缓冲流自带8KB缓冲区
-
可以提高原始字节流、字符流读写数据的性能
4.字节缓冲流的功能如何调用?
-
public BufferedOutputStream(OutputStream os)
-
public BufferedInputStream(InputStream is)
-
功能上并无很大变化,性能提升了。
2. 字符缓冲输入流
-
字符缓冲输入流:BufferedReader。
-
作用:提高字符输入流读取数据的性能,除此之外多了按照行读取数据的功能。
构造器 | 说明 |
---|---|
public BufferedReader(Reader r) | 可以把低级的字符输入流包装成一个高级的缓冲字符输入流管道,从而提高字符输入流读数据的性能 |
字符缓冲输入流新增功能
方法 | 说明 |
---|---|
public String readLine() | 读取一行数据返回,如果读取没有完毕,无行可读返回null |
3. 字符缓冲输出流
-
字符缓冲输出流:BufferedWriter。
-
作用:提高字符输出流写取数据的性能,除此之外多了换行功能
构造器 | 说明 |
---|---|
public BufferedWriter(Writer w) | 可以把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能 |
字符缓冲输出流新增功能
方法 | 说明 |
---|---|
public void newLine() | 换行操作 |
五、转换流
解决JVM默认的IO编码集与输入字符文件编码不同的问题
流程:
-
使用字符输入转换流
-
可以提取文件(GBK)的原始字节流,原始字节不会存在问题。
-
然后把字节流以指定编码转换成字符输入流,这样字符输入流中的字符就不乱码了
1. 字符输入转换流
- 字符输入转换流:InputStreamReader,可以把原始的字节流按照指定编码转换成字符输入流。
构造器 | 说明 |
---|---|
public InputStreamReader(InputStream is) | 可以把原始的字节流按照代码默认编码转换成字符输入流。几乎不用,与默认的FileReader一样。 |
public InputStreamReader(InputStream is ,String charset) | 可以把原始的字节流按照指定编码转换成字符输入流,这样字符流中的字符就不乱码了(重点) |
2. 字符输出转换流
- 字符输入转换流:OutputStreamWriter,可以把字节输出流按照指定编码转换成字符输出流。
构造器 | 说明 |
---|---|
public OutputStreamWriter(OutputStream os) | 可以把原始的字节输出流按照代码默认编码转换成字符输出流。几乎不用。 |
public OutputStreamWriter(OutputStream os,String charset) | 可以把原始的字节输出流按照指定编码转换成字符输出流(重点) |
六、对象序列化
对象序列化
- 作用:以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化。
- 使用到的流是对象字节输出流:ObjectOutputStream
- 注意:对象必须实现序列化接口——Serializable
- **序列号ID作用:**它决定着是否能够成功反序列化!java的序列化机制是通过判断运行时类的serialVersionUID来验证版本一致性的,在进行反序列化时,JVM会把传进来的字节流中的serialVersionUID与本地实体类中的serialVersionUID进行比较,如果相同则认为是一致的,便可以进行反序列化,否则就会报序列化版本不一致的异常。
- 如果没有显示指定serialVersionUID,会自动生成一个;只有同一次编译生成的class才会生成相同的serialVersionUID。
private static final long serialVersionUID = 1L;
- transient修饰序列化对象的成员变量不参与序列化
实例:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/**
* @description 使用transient关键字不序列化某个变量
* 注意读取的时候,读取数据的顺序一定要和存放数据的顺序保持一致
*
* @author Alexia
* @date 2013-10-15
*/
public class TransientTest {
public static void main(String[] args) {
User user = new User();
user.setUsername("Alexia");
user.setPasswd("123456");
System.out.println("read before Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
try {
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream("C:/user.txt"));
os.writeObject(user); // 将User对象写进文件
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
ObjectInputStream is = new ObjectInputStream(new FileInputStream(
"C:/user.txt"));
user = (User) is.readObject(); // 从流中读取User的数据
is.close();
System.out.println("\nread after Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class User implements Serializable {
private static final long serialVersionUID = 8294180014912103005L;
private String username;
private transient String passwd; // 不参与序列化
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
结果:
read before Serializable:
username: Alexia
password: 123456
read after Serializable:
username: Alexia
password: null
1. 对象序列化
- 使用到的流是对象字节输出流:ObjectOutputStream
构造器 | 说明 |
---|---|
public ObjectOutputStream(OutputStream out) | 把低级字节输出流包装成高级的对象字节输出流 |
ObjectOutputStream序列化方法
方法名称 | 说明 |
---|---|
public final void writeObject(Object obj) | 把对象写出去到对象序列化流的文件中去 |
2. 对象反序列化
-
使用到的流是对象字节输入流:ObjectInputStream
-
作用:以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化。
构造器 | 说明 |
---|---|
public ObjectInputStream(InputStream out) | 把低级字节输如流包装成高级的对象字节输入流 |
ObjectInputStream序列化方法
方法名称 | 说明 |
---|---|
public Object readObject() | 把存储到磁盘文件中去的对象数据恢复成内存中的对象返回 |
七、打印流
-
作用:打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指:PrintStream,PrintWriter两个类。
-
可以实现打印什么数据就是什么数据,例如打印整数97写出去就是97,打印boolean的true,写出去就是true。
-
打印流包装了缓冲流,高效
-
前面的输出流仅仅只能打印字符串,字符或字符的码值;PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
-
如果打印流要追加数据,需要在创建低级流时设置追加,再用低级流创建打印流,打印流就可以追加数据了;不能直接使用文件或路径的形式创建追加的打印流。
1. PrintStream
构造器 | 说明 |
---|---|
public PrintStream(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintStream(File f) | 打印流直接通向文件对象 |
public PrintStream(String filepath) | 打印流直接通向文件路径 |
方法 | 说明 |
---|---|
public void print(Xxx xx) | 打印任意类型的数据出去 |
2. PrintWriter
构造器 | 说明 |
---|---|
public PrintWriter(OutputStream os) | 打印流直接通向字节输出流管道 |
public PrintWriter (Writer w) | 打印流直接通向字符输出流管道 |
public PrintWriter (File f) | 打印流直接通向文件对象 |
public PrintWriter (String filepath) | 打印流直接通向文件路径 |
方法 | 说明 |
---|---|
public void print(Xxx xx) | 打印任意类型的数据出去 |
3. PrintStream和PrintWriter的区别
-
打印数据功能上是一模一样的,都是使用方便,性能高效(核心优势)
-
PrintStream继承自字节输出流OutputStream,支持写字节数据的方法。
-
PrintWriter继承自字符输出流Writer,支持写字符数据出去。
总结
1.打印流有几种?各有什么特点?
-
打印流一般是指:PrintStream,PrintWriter两个类。
-
打印功能2者是一样的使用方式
-
PrintStream继承自字节输出流OutputStream,支持写字节
-
PrintWrite继承自字符输出流Writer,支持写字符
2.打印流的优势是什么?
- 两者在打印功能上都是使用方便,性能高效(核心优势)
八、输出语句的重定向
我们通过查看源码发现System.out实际上是一个打印流
public final class System {
private static native void registerNatives();
static {
registerNatives();
}
···
public static final PrintStream out = null;
···
打印流out实际上是通过native方法,通过反射的方式获取值的,一般final对象可以通过反射更改,String对象因为JVM的内联优化的原因改值不能体现。
输出语句重定向
- 属于打印流的一种应用,可以把输出语句的打印位置改到文件。
九、IO框架
commons-io概述
-
commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以提高IO功能开发的效率。
-
commons-io工具包提供了很多有关io操作的类。有两个主要的类FileUtils, IOUtils
FileUtils主要有如下方法:
方法名 | 说明 |
---|---|
String readFileToString(File file, String encoding) | 读取文件中的数据, 返回字符串 |
void copyFile(File srcFile, File destFile) | 复制文件。 |
void copyDirectoryToDirectory(File srcDir, File destDir) | 复制文件夹。 |
参考: