IO流
IO:传输数据,做输入输出,拷贝,上传下载…
流:一连串流动的数据,以先入先出的方式流动,管道
- 按照流向分: 都是大脑为中心,程序为中心
- 比如: 文件(数据源)–输入流–>程序(目的地)
- 程序–输出->文件
IO:传输数据,做输入输出,拷贝,上传下载...
不同流:管道
流分类:
操作单元分类:
字节:字节的输出 字节的输入 *****
字符:
功能分:
节点流
功能流
按照流向: 以自己的单位(程序)
输入流
输出流
分类之间都是相辅相成的
流的使用
创建(参数为File,路径字符串)
功能
节点:
字节流:
输入FIleInputStream
输出FIleOutputStream
字符流
输入FileReader
输出FileWriter
功能流:
对象流
输入ObjectInputStream
输出ObjectOutputStream
流分类
字节流:
万能流,能够传输任意类型的数据
字节流读入 以程序为中心 数据源--读入-->程序
InputStream 抽象父类 字节输入流
FileInputStream 文件字节输入流,从系统文件中读入数据到程序
构造器 FileInputStream(String name) 内部会先构建File对象,然后调用下面结构File对象的构造器
new FileInputStream(File);
方法
read()->返回值int,读到的字节数据,如果没有数据返回-1 读入一个字节的数据
read(byte[]) 一个字节数组一个字节数组读入,返回读入到数组中数据的个数,如果没有读到,返回-1
注意:java中字符串中表示路径可以使用\\或者/,使用\会识别成为转义字符
字节输出流:
OutputStream 抽象父类
FileOutputStream 文件字节输出流
构造器
FileOutputStream(String name) 创建一个文件输出流写入文件指定名称。
默认覆盖原有内容
FileOutputStream(String name, boolean append)写出 并且追加。
常用方法
write(int)
write(byte[] b)
write(byte[] b, int off, int len)
flush() 只要是输出流都要记得关闭之前刷出
close()
写出的时候,如果文件系统中不存在,系统会自动帮你创建一个,但是如果是目录不存在,系统不会创建
示例:
数据源文件----->程序------>目的地文件
文件拷贝:
1.创建流
文件字节输入流
文件字节输出流
2.先读入 后写出
3.刷出
4.关闭(后打开的先关闭)
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class CopyFile03 {
public static void main(String[] args) {
//1.创建流
InputStream is=null;
OutputStream os=null;
try {
/*is=new FileInputStream("D:/test.txt");
os=new FileOutputStream("E:/test.txt");*/
//2.先读入 后写出
byte[] car=new byte[1024];
int len=-1;
while(-1!=(len=is.read(car))){
os.write(car, 0, len);
}
//3.刷出
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{ //无论try中是否出现异常代码,都会执行finally中的关闭功能
//4.关闭(后打开的先关闭)
try {
if(os!=null){ //预防空指针异常出现
os.close();
}
if(is!=null){ //预防空指针异常出现
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
字符流:
纯文本
只能拷贝纯文本的数据
- 输入流: Reader FileReader read() read(char[]) close()
- 输出流: Writer FileWriter write() + flush() close()
示例:
public class CharIODemo04 {
public static void main(String[] args) throws IOException {
//1.选择流
Reader rd=new FileReader("D:/test.txt");
Writer rt=new FileWriter("D:/haha.txt");
//2.读写
char[] car=new char[1024];
int len=-1; //读入到数组中数个数
while((len=rd.read(car))!=-1){
rt.write(car, 0, len);
}
//3.刷出
rt.flush();
//4.关闭
rt.close();
rd.close();
}
}
节点流:真实用来传输数据,数据从数据源到目的地
功能流:扩展节点流的功能
对象流 :
读写对象|任意类型数据 保留数据+数据类型
- 使用: 功能流(节点流)
- 功能流:提高节点流的功能,增强性能
- ObjectInputStream 对象|反序列化输入流 新增方法:readXxx()
- ObjectOutputStream 对象|序列化字节输出流 新增方法:writeXxx()
-
注意:不能发生多态
- 序列化:把对象数据转为可存储或者可传输的过程,成为序列化
- 不是所有的类型都能够序列化 java.io.Serializable
- 先序列化后反序列化
- 读写的内容顺序保持一致
- 不是所有的属性都需要序列化 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;
public class ObjectDemo05 {
public static void main(String[] args) throws Exception {
write("D:/haha.txt");
read("D:/haha.txt");
}
//序列化输出
//参数name: 目的地文件的路径
public static void write(String name) throws FileNotFoundException, IOException{
//1.输出流
ObjectOutputStream os=new ObjectOutputStream(new FileOutputStream(name));
Person p=new Person("张三",123);
//2.写出
os.writeBoolean(false);
os.writeUTF("HAHA");
os.writeObject(p);
//3.刷出
os.flush();
//4.关闭
os.close();
// p.age=20;
}
//反序列化输入
public static void read(String name) throws Exception{
//1,选择流
ObjectInputStream is = new ObjectInputStream(new FileInputStream(name));
//2.读入
boolean b=is.readBoolean();
String s=is.readUTF();
Object o=is.readObject();
System.out.println(b+"-->"+s+"-->"+o);
//3.关闭
is.close();
}
}
四大接口
消费性接口
Consumer
void accept(T t)
//消费性接口 Consumer<T>
//void accept(T t)
@Test
public void Test() {
test("我是谁?",(str1)->System.out.println(str1));
}
public void test(String str,Consumer<String> c) {
c.accept(str);
}
供给型接口
Supplier
T get()
//供给型接口 Supplier<T>
// T get()
@Test
public void test1() {
List li=test1(8,()->(int)(Math.random()*(100-1-1)+1));
System.out.println(li);
}
public List<Integer> test1(Integer num,Supplier<Integer> s) {
List<Integer> list=new ArrayList();
for(int i=1;i<=num;i++) {
list.add(s.get());
}
return list;
}
函数型接口
Function<T,R>
R apply(T t)
//函数型接口 Function<T,R>
//R apply(T t)
@Test
public void test3() {
System.out.println(test3("新的一天即将到来!",(str)->str.substring(0, 4)));
}
public String test3(String str,Function<String,String> s1) {
return s1.apply(str);
}
断定型接口
Predicate
boolean test(T t)
//断定型接口 Predicate<T>
// boolean test(T t)
@Test
public void test4() {
System.out.println(test4("",(str)->str.equals("")));
}
public boolean test4(String str,Predicate<String> p) {
return p.test(str);
}
方法引用:
- 简化Lambda表达式,可以理解为Lambda表达式的另一种表现形式
- 前提: 当重写的抽象方法方法体的实现,其实就是通过调用另外一个已有的方法进行实现,可以通过方法引用进行调用,简化Lambda的写法
- 对象的引用 ::成员方法;
- 类名::静态方法名;
- 类名::成员方法;
- 要求: 函数型接口的抽象方法的参数列表和返回值要求与内部引用的方法的参数列表和返回值保持一致!!!
- 构造器引用:
- new Person();
- Person::new;
- 类型::::new;
public class MethodDemo02 {
/*
* 构造器引用
*/
@Test
public void test5(){
// Supplier<Employee> sup=()->new Employee();
Supplier<Employee> sup=Employee::new;
Function<Integer,Employee> fun=(i)->new Employee(i);
Function<Integer,Employee> fun2=Employee::new;
}
/*
* 类名::成员方法;
* 如果抽象方法只有一个参数,作为调用|引用的方法的对象
* 如果抽象方法有两个参数,第一个作为调用方法的对象,第二个开始作为调用方法的参数
*/
@Test
public void test4(){
// BiPredicate<String, String> bi=(s1,s2)-> s1.equals(s2);
BiPredicate<String, String> bi=String::equals;
System.out.println(bi.test("zhangsan","zha2ngsan"));;
}
/*
* 类名::静态方法名;
* 抽象方法的参数列表与引用的方法的参数列表保持一致,返回值保持一致
*/
@Test
public void test3(){
// Comparator<Integer> com=(d1,d2)->{return Integer.compare(d1, d2);};
Comparator<Integer> com=Integer::compare;
System.out.println(com.compare(1, 2));;
}
/*
* 对象的引用::成员方法->简化Lambda结构
*/
@Test
public void test2(){
List<String> ls=Arrays.asList("aa","bb","cc","dd");
//ls.forEach((e)->{System.out.println(e)});
ls.forEach(System.out::println);
}
@Test
public void test1(){
PrintStream p=System.out;
// Consumer com=(e)->{System.out.println(e);};
// Consumer com=(e)->{p.println(e);};
Consumer com=System.out::println;
com.accept("haha");
com.accept("hehe");
com.accept("heihei");
com.accept("houhou");
}
}