第五章 Stream流与IO流 v1.0
第一部分 Stream流
一、获取Stream流对象
1.数组
//通过数组工具类
Stream<泛型> 对象名 = Arrays.stream(array);
//通过Stream类
Stream<泛型> 对象名 = Stream.of(array);2.Collection类
Stream<泛型> 对象名 = list.stream();3.Map类
//获取键的Stream流
Stream<泛型> 对象名 = map.keySet.stream();
//获取值的Stream流
Stream<泛型> 对象名 = map.values.stream();
//获取键值对(整体)的Stream流
Stream<Map.Entry<泛型, 泛型>> 对象名 = map.entrySet.stream();二、操作Stream流
用于简化集合和数组操作的API。
1.常用中间操作(非终结)方法
中间操作方法调用完成后返回新的Stream流可以继续使用,支持链式编程
2.常见终结操作方法
3.使用方法引用进行操作
list.stream().map(Student::new).forEach(System.out::println); //构造对象并遍历三、收集Stream流
将操作完成的Stream流转为集合或数组对象,要注意:流只能使用一次,收集一次之后无法再次收集
收集Stream流的方法
//收集为集合类对象
集合类型名<泛型> 对象名 = s.collect(Collectors.方法名()); //常用收集方法:toSet,toList,toMap
//收集为数组
Object[] 对象名 = s.toArray(); //流中数据类型不确定,一般用Object类型
//String[] 对象名 = s.toArray(String[]::new); //例:转为String类型数组,一般不使用第二部分 基础IO流
一、File类
File类代表操作系统的文件对象,提供了诸如:定位文件,获取文件信息、删除文件、创建文件等功能。
1.Java文件路径
File类支持绝对路径与相对路径,一般相对路径对应到所创建工程的根目录(作为.目录)
|-project #视为当前目录
├─module #./module
├─src #./module/src/main
├─main #./module/src/main
│ ├─java #./module/src/main/java
│ └─resources #./module/src/main/resources
└─test #./module/src/test
└─java #./module/src/test/java2.创建File类对象
常用File类构造方法
File(String path):根据文件路径创建文件对象File(String parent, String child):根据父路径和子文件路径创建文件对象File(File parent, String child):根据父文件对象和子文件路径创建文件对象
3.常见方法
a.文件信息获取
b.创建与删除文件
二、IO流概述
代表任何有能力产出数据的数据源对象或是接受数据的接收端对象,用于数据传输、读写数据
1.IO流分类
- 字节输入流:以内存为基准,来自磁盘文件/网络中的数据以字节的形式读入到内存中去的流
- 字节输出流:以内存为基准,把内存中的数据以字节写出到磁盘文件或者网络中去的流
- 字符输入流:以内存为基准,来自磁盘文件/网络中的数据以字符的形式读入到内存中去的流
- 字符输出流:以内存为基准,把内存中的数据以字符写出到磁盘文件或者网络介质中去的流
2.字符集
a.ASCII字符集
包括数字、英文、符号,ASCI使用一个字节存储一个字符,总共可以表示128个字符信息
b.GBK字符集
window系统默认的码表,兼容ASCII码表,也包含了几万个汉字,并支持繁体汉字以及部分日韩文字。
GBK是中国的码表,一个中文以两个字节的形式存储,但不包含世界上所有国家的文字。
c.Unicode字符集
Unicode(又称统一码、 万国码、单一码)是计算机科学领域里的一项业界字符编码标准,常见的为UTF-8
Unicode容纳世界上大多数国家的所有常见文字和符号,以UTF-8编码后一个中文一般以三个字节的形式存储
d.关于字符长度
- 英文和数字等在任何国家的字符集中都占1个字节
- GBK字符中一个中文字符占2个字节
- UTF-8编码中一个中文一般占3个字节
3.字符串的编码与解码
字符串编码:byte[] bytes = s.getBytes("字符集")
字符串解码:String s = String(byte[] bytes, "字符集")
三、字节流
1.文件字节输入流(FileInputStream)
a.常见构造方法
FileInputStream(File file):根据文件对象创建文件字节输入流FileInputStream(String path):根据文件路径创建文件字节输入流
b.读取文件内容方法
read():每次读取一个字节返回,如果字节已经没有可读的返回-1read(byte[] b):每次读取一个字节数组,返回读取到的字节数组长度,读取完毕返回-1
c.示例
try(InputStream is = new FileInputStream(StaticConfig.getPngFile())){
//每次读取一个字节返回,如果字节已经没有可读的返回-1
int aByte=is.read();
//每次读取一个字节数组,返回读取到的字节数组长度,读取完毕返回-1
byte[] b=new byte[100];
int statusCode=is.read(b);
System.out.println(aByte); //输出:137(此时是int类型)
System.out.println((byte)aByte); //输出:-119(此时为byte类型,但byte类型是有符号的)
}catch (IOException e){
e.printStackTrace();
}
try(InputStream is = new FileInputStream(StaticConfig.getPngFile())){
//每次读取一个字节数组,返回读取到的字节数组长度,读取完毕返回-1
byte[] b=new byte[100];
int statusCode=is.read(b);
System.out.println(b[0]); //输出:-119
}catch (IOException e){
e.printStackTrace();
}2.文件字节输出流(FileOutputStream)
a.常见构造方法
FileOutputStream(File file):根据文件对象创建文件字节输出流FileOutputStream(String path):根据文件路径创建文件字节输出流FileOutputStream(File file, boolean append):根据文件对象创建追加数据的文件字节输出流FileOutputStream(String path, boolean append):根据文件路径创建追加数据的文件字节输出流
b.写入文件内容的方法
write(int b):将指定的字符写入文件中write(byte[] b):将字节流写入文件中flush():刷新缓存,立即写入
3.示例:使用字节流复制图片
try {
// 创建输入流和输出流
InputStream inputStream = new FileInputStream("source.jpg");
OutputStream outputStream = new FileOutputStream("destination.jpg");
// 创建缓冲区
byte[] buffer = new byte[1024];
int bytesRead;
// 从输入流读取数据,并写入到输出流中
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
// 关闭输入流和输出流
inputStream.close();
outputStream.close();
System.out.println("图片复制完成!");
} catch (IOException e) {
e.printStackTrace();
}4.释放资源
输入输出流在使用完毕之后需要对有限的操作系统资源进行释放,否则会导致系统资源被耗尽
a.常规方式(手动释放资源)
在异常处理时提供finally块来执行所有清除操作,比如说IO流中的释放资源
OutputStream fos = null;
try {
fos = new FileOutputStream("文件名");
// 相关文件操作
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
fos.close();
}
}b.自动释放资源(JDK7引入)
try (OutputStream fos = new FileOutputStream("文件名")) { //定义流对象
// 相关文件操作
} catch (IOException e) {
e.printStackTrace();
}四、字符流
1.文件字符输入流(FileReader)
a.常见构造方法
FileReader(File file):根据文件对象创建文件字符输入流FileReader(String path):根据文件路径创建文件字符输入流
b.读取文件内容的方法
read():每次读取一个字符的编号返回,如果字节已经没有可读的返回-1read(char[] b):每次读取一个字符数组,返回读取到的字符数组长度,读取完毕返回-1
try(
Reader file=new FileReader("文件名"); //在此处声明的资源使用完毕会自动释放
) {
char[] buffer = new char[1024];
int len;
while ((len = file.read(buffer)) != -1) {
String rs = new String(buffer, 0, len);
System.out.print(rs);
}
} catch (IOException e){
e.printStackTrace();
}2.文件字符输出流(FileWriter)
a.常见构造方法
FileWriter(File file):根据文件对象创建文件字符输出流FileWriter(String path):根据文件路径创建文件字符输出流FileWriter(File file, boolean append):根据文件对象创建追加数据的文件字符输出流FileWriter(String path, boolean append):根据文件路径创建追加数据的文件字符输出流
b.写入文件内容的方法
write(int b):将指定的字符写入文件中write(char[] b):将字符流写入文件中write(String str):将字符串写入文件中
try(Writer file=new FileWriter("文件名", true)) { //以追加模式打开文件
file.write("写入文本信息\n")
}catch (IOException e){
e.printStackTrace();
}第三部分 高级IO流
一、缓冲流
缓冲流自带(8KB)缓冲区、可以提高原始字节流、字符流读写数据的性能,读写数据的性能更好
1.字节缓冲输入流(BufferedInputStream)
构造方法:BufferedInputStream(InputStream is)
2.字节缓冲输出流(BufferedOutputStream)
构造方法:BufferedOutputStream(InputStream os)
3.字符缓冲输入流(BufferedReader)
构造方法:BufferedReader(Reader fr)
独有成员方法:readLine():读取一行数据返回字符串,如果读取没有完毕,无行可读返回null
4.字符缓冲输出流(BufferedWriter)
构造方法:BufferedWriter(Writer fw)
独有成员方法:newLine():实现换行功能
二、转换流
用于文件字符编码与代码指定编码不一致等情况下转化
1.字符输入转换流(InputStreamReader)
构造方法:InputStreamReader(InputStream is, String charset);
2.字符输出转换流(OutputStreamWriter)
构造方法:OutputStreamReader(OutputStream os, String charset);
三、序列化
用于将Java对象进行长久化保存
1.序列化对象前提条件
待序列化的对象实现了Serializable序列化接口
2.对象序列化(对象字节输出流,ObjectOutputStream)
以内存为基准,把内存中的对象存储到磁盘文件中去,称为对象序列化。
构造方法:ObjectOutputStream(OutputStream os):把低级字节输出流包装成高级的对象字节输出流
序列化对象使用方法:writeObject(Object o) //将内存中对象存储到磁盘文件
3.对象反序列化(对象字节输入流,ObjectInputStream)
以内存为基准,把存储到磁盘文件中去的对象数据恢复成内存中的对象,称为对象反序列化。
构造方法:ObjectInputStream(InputStream is);:把低级字节输入流包装成高级的对象字节输入流
反序列化对象使用方法:readObject(Object o) //将存储到磁盘文件中的对象重新读取到内存中
4.序列化过程中的敏感信息处理
可以使用transient标记成员变量使之不参与序列化
public class Student implements Serializable {
private String name;
private String loginName;
private transient String passWord; //此字段不参与序列化,不会保存
...
}5.序列化版本号
待序列化对象中可以定义成员变量:private static final Long serialVersionUID = <版本号>;
当使用序列化版本号时,序列化的版本号与反序列化的版本号必须一致才不会出错
四、打印流
使用方便且性能高效(底层通过缓冲流实现)的输出流,打印输出在控制台是什么数据,输出流中就是什么数据
打印功能(类似System.out)PrintStream与PrintWriter基本没有区别,只在写数据存在区别(但是基本不会使用)
1.字节打印流(PrintStream)
常用构造方法:
PrintStream(OutputStream os):打印流直接通向字节输出流管道PrintStream(File f):打印流直接通向文件对象PrintStream(String filepath):打印流直接通向文件路径
2.字符打印流(PrintWriter)
常见构造方法:
PrintWriter(OutputStream os):打印流直接通向字节输出流管道PrintWriter(Writer w):打印流直接通向字符输出流管道PrintWriter(File f):打印流直接通向文件对象PrintWriter(String filepath):打印流直接通向文件路径
3.System.out输出原理
实际上System.out对应的是一个默认的PrintStream对象,默认将输出打印到控制台中
PrintStream ps = new PrintStream("文件名");
System.setOut(ps); //把系统打印流改成我们自己的打印流
//此后System.out输出语句输出的内容即从控制台修改为对应文件五、Properties
1.Properties简介
属于Map集合体系,代表的是一个属性文件,可以把自己对象中的键值对信息存入到一个属性文件中去。
属性文件:后缀是.properties结尾的文件,里面的内容都是键值对,常用于进行系统信息配置。
2.常用方法
a.操作属性
setProperties(String key, String value):保存属性键值对到该Properties对象(对应keySet())
getProperties(String key):使用此属性列表中指定的键搜索属性值(对应get())
stringPropertyNames():获取所有键的名称的集合(对应keySet())
b.保存属性键值对到流
load(InputStream iStream):从输入字节流读取属性列表(键和元素对)
load(Reader reader):从输入字符流读取属性列表(键和元素对)
c.从流读取属性键值对
store(OutputStream oStream, String comments):将属性列表(键和元素对)写入该Properties对象
store(Writer writer, String comments):将属性列表(键和元素对)写入该Properties对象
六、IO框架(commons-io)
1.FileUtils

2.IOUtils
暂略