IO流和Lambda 表达式
1. IO 分类
完成数据在文件和文件直接的传递过程。对于计算机而言,所有的内容都是文件!!!所有的内容,设备,数据都看作是文件内容,通过读写操作对文件数据进行提取和写入操作。计算机之父【冯·诺依曼】设计的基础原理。
按照处理数据单位:
字节流
数据每一次读取和写入操作基础单位为字节
使用场景很多 视频,音频,图片,文本文件...
字符流
数据每一次读取和写入操作基础单位为字符,字符需要根据当前所处计算机环境对应的默认字符集进行数据二次解
析。
字符流 ==> 字节 + 解码(根据当前计算机对应字符集进行解码)
有且只能处理通过【记事本】打开的非乱码的可读文本文件。
按照处理流向分析:
参照物 【内存】
输入流:
数据流向内存方向,为输入流
输出流:
数据从内存流出,为输出流
例如:
保存数据到硬盘上的一个 .doc 文件。输出流
从硬盘读取游戏必要运行资源到内存。 输入流
我通过内网通发送群消息给大家。输出
大家看到群消息。 输入
IO流操作基础类:
字节输入流 InputStream
字节输出流 OutputStream
字符输入流 Reader
字符输出流 Writer
2. 文件相关字节流操作
2.1 文件字节输入流
class FileInputStream extends InputStream
构造方法:
FileInputStream(String fileName);
根据文件路径创建对应的 FileInputStream 字节输入流对象
FileInputStream(File file);
根据文件对应的 File 对象,创建 FileInputStream 字节输入流对象
成员方法:
int read();
从文件中读取一个字节数据到当前 Java 程序,返回值为 int 类型,实际有效数据为 byte 类型。
int read(byte[] buf);
从文件中读取数据到 byte 类型的缓冲数组,返回值类型是读取到的文件内容字节个数
int read(byte[] buf, int off, int len);
从文件中读取数据到 byte 类型的缓冲数组,要求从数组 off 下标开始记录数据,同时要求最大长度为 len,返
回值类型是读取到的文件内容字节个数
【注意】
以上方法如果返回值为 -1 表示读取数据到文件末尾 EOF End of Filex
package com.qfedu.a_byteStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
}
private static void read2() throws FileNotFoundException, IOException {
String filePath = "G:/aaa/1.txt";
FileInputStream fis = new FileInputStream(filePath);
byte[] buf = new byte[1024 * 4];
int length = -1;
while ((length = fis.read(buf)) != -1) {
System.out.println(new String(buf, 0, length));
}
fis.close();
}
private static void read1() throws FileNotFoundException, IOException {
String filePath = "G:/aaa/1.txt";
FileInputStream fis = new FileInputStream(filePath);
int content = -1;
while ((content = fis.read()) != -1) {
System.out.println((char) content);
}
fis.close();
}
}
2.2 文件字节输出流
class FileOutputStream extends OutputStream
构造方法:
FileOutputStream(String fileName);
根据用户指定的文件路径,打开对应文件的字节输出流
FileOutputStream(File file);
根据用户指定的文件对应 File 对象,打开对应文件的字节输出流
FileOutputStream(String fileName, boolean append);
根据用户指定的文件路径,打开对应文件的字节输出流
append 追加写标记为 true,当前文件内容保留,后期添加从文件末尾添加数据
FileOutputStream(File file, boolean append);
根据用户指定的文件对应 File 对象,打开对应文件的字节输出流
append 追加写标记为 true,当前文件内容保留,后期添加从文件末尾添加数据
注意:
1. FileOutputStream 如果对应文件不存在,同时文件对应路径有效合法,并且有可写入数据权限,
FileOutputStream 可以创建对应文件。
2. FileOutputStream 默认数据写入到文件的方式是【删除写】,如果需要追加写,需要在构造方法中添加追加
写标记
成员方法:
void write(int b);
在对应文件中写入一个字节(byte)数据
void write(byte[] buf);
在对应文件中,写入整个byte 类型数组数据
void write(byte[] buf, int off, int len);
在对应文件中,写入 byte 类型数组中,从下标 off 位置开始,到 len 计数个数对应的数据内容。
2.3 文件字符输入流
class FileReader extends Reader
构造方法:
FileReader(String fileName);
根据文件路径创建对应的 FileReader 字符输入流对象
FileReader(File file);
根据文件对应的 File 对象,创建 FileReader 字符输入流对象
成员方法:
int read();
从文件中读取一个字符数据到当前 Java 程序,返回值为 int 类型,实际有效数据为 char 类型。
int read(char[] buf);
从文件中读取数据到 char 类型的缓冲数组,返回值类型是读取到的文件内容字符个数
int read(char[] buf, int off, int len);
从文件中读取数据到 char 类型的缓冲数组,要求从数组 off 下标开始记录数据,同时要求最大长度为 len,返
回值类型是读取到的文件内容字符个数
【注意】
以上方法如果返回值为 -1 表示读取数据到文件末尾 EOF End of Filex
package com.qfedu.b_charStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class Demo1 {
public static void main(String[] args) throws IOException {
}
private static void read2() throws FileNotFoundException, IOException {
String filePath = "G:/aaa/1.txt";
FileReader fr = new FileReader(filePath);
char[] buf = new char[1024 * 4];
int length = -1;
while ((length = fr.read(buf)) != -1) {
System.out.println(new String(buf, 0, length));
}
fr.close();
}
private static void read1() throws FileNotFoundException, IOException {
String filePath = "G:/aaa/1.txt";
FileReader fr = new FileReader(filePath);
int content = -1;
while ((content = fr.read()) != -1) {
System.out.println((char) content);
}
fr.close();
}
}
2.4 文件字符输出流
class FileWriter extends Writer
构造方法:
FileWriter(String fileName);
根据用户指定的文件路径,打开对应文件的字符输出流
FileWriter(File file);
根据用户指定的文件对应 File 对象,打开对应文件的字符输出流
FileWriter(String fileName, boolean append);
根据用户指定的文件路径,打开对应文件的字符输出流
append 追加写标记为 true,当前文件内容保留,后期添加从文件末尾添加数据
FileWriter(File file, boolean append);
根据用户指定的文件对应 File 对象,打开对应文件的字符输出流
append 追加写标记为 true,当前文件内容保留,后期添加从文件末尾添加数据
注意:
1. FileWriter 如果对应文件不存在,同时文件对应路径有效合法,并且有可写入数据权限,
FileWriter 可以创建对应文件。
2. FileWriter 默认数据写入到文件的方式是【删除写】,如果需要追加写,需要在构造方法中添加追加
写标记
成员方法:
void writer(String str);
void write(int ch);
在对应文件中写入一个字符(char)数据
void write(char[] buf);
在对应文件中,写入整个 char 类型数组数据
void write(char[] buf, int off, int len);
在对应文件中,写入 char 类型数组中,从下标 off 位置开始,到 len 计数个数对应的数据内容。
void writer(String str);
在对应文件中,写入 String 类型字符串
void writer(String str, int off, int len);
在对应文件中,写入 String 类型字符串,从下标 off 位置开始,到 len 计数个数对应的数据内容。
2. Lambda 表达式
2.1 无参数无返回 Lambda
需要定义一个接口,并且接口中有且只有一个未完成的方法!!!就一个函数式接口,最好使用 @FunctionalInterface 开启检查
@FunctionalInterface
interface A {
void test();
}
准备一个方法,方法参数是接口 A 类型
public static void testLambda(A a) {
a.test();
}
package com.qfedu.c_lambda;
@FunctionalInterface
interface A {
void test();
}
class TypeA implements A {
@Override
public void test() {
System.out.println("实现类 TypeA 实现完成 test 方法");
}
}
public class Demo1 {
public static void main(String[] args) {
testLambda(new TypeA());
testLambda(new A() {
@Override
public void test() {
System.out.println("匿名内部类的匿名对象,直接作为方法的参数");
}
});
testLambda(() -> {
System.out.println("Lambda表达式直接作为方法的参数");
});
testLambda(() -> System.out.println("如果Lambda表达式只有一行,可以省略大括号"));
}
public static void testLambda(A a) {
a.test();
}
}
2.2 有参数无返回 Lambda
需要定义一个接口,并且接口中有且只有一个未完成的方法!!!就一个函数式接口,最好使用
@FunctionalInterface 开启检查
@FunctionalInterface
interface Consumer {
void accept(String str);
}
package com.qfedu.c_lambda;import javax.activation.CommandInfo;
@FunctionalInterface
interface Consumer {
void accept(String str);
}
public class Demo1 {
public static void main(String[] args) {
testLambda("北平在不在???", new Consumer() {
@Override
public void accept(String str) {
System.out.println(str);
}
});
testLambda("有问题就问!!!不会就问!!!截图问,语音问,不行电话问!!!", (s) -> {
System.out.println(s);
});
testLambda("Lambda简化!!!", s -> System.out.println(s));
testLambda("方法引用!!!", System.out::println);
testLambda("方法引用!!!", Demo1::parseString);
}
public static void testLambda(String str, Consumer consumer) {
consumer.accept(str);
}
public static void parseString(String str) {
System.out.println(str.length());
}
}
2.3 无参数有返回 Lambda
@FunctionalInterface
interface Supplier {
int get();
}
package com.qfedu.c_lambda;
@FunctionalInterface
interface Supplier {
int get();
}
public class Demo2 {
public static void main(String[] args) {
int[] arr = {1, 3, 5, 7, 19, 2, 4, 6, 8, 10};
int maxIndex = testLambda(() -> {
int index = 0;
for (int i = 1; i < arr.length; i++) {
if (arr[index] < arr[i]) {
index = i;
}
}
return index;
});
System.out.println(maxIndex);
}
public static int testLambda(Supplier supplier) {
return supplier.get();
}
}
2.4 有参数有返回 Lambda ☆
@FunctionalInterface
interface Predicate {
boolean test(String str);
}
package com.qfedu.c_lambda;
@FunctionalInterface
interface Predicate {
boolean test(String str);
}
public class Demo3 {
public static void main(String[] args) {
String str = "噶周董腰子两个用于校区建设";
boolean ret = testLambda(str, (s) -> {
return s.length() > 20;
});
System.out.println(ret);
ret = testLambda(str, s -> s.length() > 10);
System.out.println(ret);
}
public static boolean testLambda(String str, Predicate predicate) {
return predicate.test(str);
}
}
2.5 Lambda + 泛型案例
package com.qfedu.c_lambda;
import java.util.Arrays;
import java.util.Comparator;
interface HandlerNumber {
int sum(int n1, int n2, int n3);
}
public class Demo4 {
public static void main(String[] args) {
Person[] arr = {
new Person(1, "周董", 56),
new Person(2, "北平", 76),
new Person(3, "王老师", 16),
new Person(4, "王乾", 26),
new Person(5, "刘某", 15),
new Person(6, "智广", 66)
};
Arrays.sort(arr, (p1, p2) -> p1.getAge() - p2.getAge());
for (Person person : arr) {
System.out.println(person);
}
int testLambda = testLambda(10, 20, 30, (n1, n2, n3) -> n1 + n2 + n3);
System.out.println(testLambda);
}
public static int testLambda(int num1, int num2, int num3, HandlerNumber hn) {
return hn.sum(num1, num2, num3);
}
}