IO流
打印流
底层提供打印或者打印换行的功能(打印就是写出) System.out以及System.err都是打印流
public class PrintStreamDemo {
public static void main(String[] args) throws IOException {
//打印流
PrintStream ps=new PrintStream("D:\\abc.txt");
//写数据
ps.write("abc".getBytes());
//打印到具体的位置---写出
ps.print("123");
//打印到具体位置----写出---换行
ps.println("123");
ps.print("123");
}
}
合并流
需要提供多个输入流的对象,存储在vector集合对象中,获取Enumeration对象,最后构建成合并流对象,合并就是把所有的数据进行统一的读取 注意输入流的编码以及格式
package cn.tedu.sequence;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
/**
*@author 作者:
*@version 创建时间:2020年11月1日下午4:17:40
*@description 描述:合并流
*/
public class SquenceInputStreamDemo {
public static void main(String[] args) throws IOException {
//提供输入流
FileInputStream fis1=new FileInputStream("D:\\a\\配置1.mp4");
FileInputStream fis2=new FileInputStream("D:\\a\\配置2.mp4");
FileInputStream fis3=new FileInputStream("D:\\a\\配置3.mp4");
//创建Vector集合对象
Vector<FileInputStream> v=new Vector<FileInputStream>();
//把输入流对象添加到集合中
v.add(fis1);
v.add(fis2);
v.add(fis3);
//获取Enumeration-----把集合中的所有输入流对象存放到e对象中
Enumeration<FileInputStream> e=v.elements();
//创建合并流对象
SequenceInputStream sis=new SequenceInputStream(e);
//文件字节输出流
FileOutputStream fos=new FileOutputStream("D:\\a\\合并.mp4");
//通过合并流对象进行统一读取数据-----合并
byte[] bs=new byte[1024*1024*10];//10M
int len=-1;
while ((len=sis.read(bs))!=-1) {
//写出合并之后的数据
fos.write(bs, 0, len);
}
//关流----建议从小到大关流
sis.close();
fos.close();
}
}
双向流
CPU–>内存—>硬盘--------rws
CPU—>硬盘--------rwd
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
//创建双向流对象-----“rw”----支持读和写
RandomAccessFile raf=new RandomAccessFile("D:\\a\\c.txt", "rw");
//写出数据-----操作数据时会自动移动下标
raf.write("123456789".getBytes());
/*//设置数据操纵的下标
raf.seek(0);
//读取数据----当要读取数据时下标移动到没有数据的位置-----输出-1
System.out.println((char)raf.read());*/
//设置下标进行写数据
raf.seek(9);
raf.write("dsfasdfasd".getBytes());
}
}
可以指定文件的访问模式----rw(可以读和写),操作数据时下标会自动进行移动,也可以指定下标进行数据操作
序列化和反序列化
序列化:把要传输的对象以及相关信息(相关属性,没有方法)转成对应的字节数组进行存储
如果字节数组存储在硬盘中–持久化—落地
反序列化:把字节数组转回成相应的对象
注意:
1、对象要进行序列化要保证对象对应的类实现Serializable接口
2、加上static或者transient的属性不能被序列化
3、实现接口的这个类如果没有指定序列化版本号(serialVersionUID),Java就会在底层根据属性和方法算出当时的版本号,这个算出来的版本号会随着对象一起序列化出去,反序列化的时候就会获取到序列化过来的版本号。去计算此时的类的属性和方法的版本号,反序列化的时候会拿着序列化过来的版本号和刚才计算好的版本号进行比较,如果两个版本号相等就反序列化成功,如果两个版本号不相等就反序列化失败 为了保证每次反序列化成功就要在类中指定序列化版本号(private static final long修饰)
4、集合和映射对象都不能序列化,只能遍历集合或者映射的对象-----一一去序列化存储的对象
package cn.tedu.io.serial;
import java.io.Serializable;
/**
*@author 作者:
*@version 创建时间:2020年11月1日下午5:11:35
*@description 描述:
*/
//想要让对象序列化需要保证对象对应的类实现Serializable接口
public class Person implements Serializable{
//指定序列化的版本号
//private static final long serivlVersionUID=-2873462L;
private static final long serivlVersionUID=-6578314028441042198L;
private String name;
private int age;
private char gender;
private char a;
//教室---共享---不能序列化
static String classroom;
//身高----不想序列化----手动操作
transient double height;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建对象
Person p=new Person();
//给对象赋值
p.setName("lili");
p.setAge(20);
//开始及逆行序列化---创建序列化对象
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("p.data"));
//写出对象
oos.writeObject(p);//把对象进行序列化
//关流
oos.close();
}
}
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建反序列化对象
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("p.data"));
//读取对象----保证获取的是传入的对象
Person p=(Person)ois.readObject();
//关流
ois.close();
//获取对象的属性
System.out.println(p.getName()+","+p.getAge());
}
}
Properties(配置文件)
可持久化的映射类 继承Hashtable 键和值都是字符串 生成的配置文件的后缀是.properties,默认编码是西欧编码,中文转不了,按u16进行编码 配置文件可以随意改动
public class PropertiesDemo1 {
public static void main(String[] args) throws FileNotFoundException, IOException {
//创建对象
Properties p=new Properties();
//添加元素---键和值---字符串
p.setProperty("name", "lili");
p.setProperty("gender", "女");
p.setProperty("age", "20");
//把要存储的内容传输到配置文件中------配置文件后缀必须是.properties
//第二个参数是文件的内容解释
p.store(new FileOutputStream("p.properties"), "xxxx");
}
}
public class PropertiesDemo2 {
public static void main(String[] args) throws FileNotFoundException, IOException {
//创建对象
Properties p=new Properties();
//加载配置文件
p.load(new FileInputStream("p.properties"));
/*
//获取配置文件的内容
//根据键获取值
System.out.println(p.getProperty("name"));
System.out.println(p.getProperty("name", "tom"));*/
//列出配置文件信息
p.list(System.out);
}
}
单元测试
可以支持单元测试的方法(三无)—没有static、没有返回值、没有参数
public class JunitDemo {
/*public static void main(String[] args) {
System.out.println(000);
}*/
//加上单元测试----基于main方法来执行
@Test
public void m() {
System.out.println(1);
}
//空白处右击所有的单元测试都执行
@Test
public void n() {//形参用于接受传递的参数
System.out.println(2);
m(34);
}
public void m(int n) {
System.out.println(n);
}
}
断言(assert)
对程序的结果进行预测性的判断 assert—关键字
需要进行手动开启(-ea) 右键----run as—configurations—arguments—VM arguments
jdk1.7新特性 -----10_00_0(数字分割)、异常分组捕获()、switch-case(String)、泛型的写法、
try-with-resources
jdk1.8新特性—接口中允许定义实体方法、lambda表达式、函数式接口、方法内部类拿到的方法是隐式常量、Stream、链式栈结构超过8个转成二叉树、Java.time(localdate)
jdk1.5新特性:泛型、增强for循环、自动封箱/拆箱、switch-case(支持枚举)、静态导入、可变参数、枚举、反射、注释、内省、动态代理
静态导入
导入类中的静态方法直接使用 优先加载导入的静态方法
package cn.tedu.jdk5;
//静态导入----导入的是类中的静态方法
//import static 包名.类名.方法名;
//import static java.lang.Math.random;
import static java.lang.Math.*;
/**
*@author 作者:
*@version 创建时间:2020年11月8日下午10:00:18
*@description 描述:静态导入
*/
public class StaticImportDemo {
public static void main(String[] args) {
//保证方法是静态
//System.out.println(Math.random());
System.out.println(java.lang.Math.random());
System.out.println(random());
System.out.println(abs(-3.2));
}
}
可变参数
…代表可变参数------底层就是有数组来接收所有的参数值
可变参数只能出现一次而且只能在最右边
public class VarsDemo {
public static void main(String[] args) {
System.out.println(m(3));//n[0]
System.out.println(m(2,3));//n[0],n[1]
//System.out.println(m());//没往参数里边存储---报错---下标越界
}
//...可变参数----表示可以接收多个这样类型的参数
//可变参数底层就是一个数组,参数的值依次存放在数组元素中
//可变参数一直在最右边,而且只有一个
public static int m(double m,int ...n) {//n[]
//return n[0];
return (int)m;
}
}