java20
IO流
打印流
底层提供打印或者打印换行功能(打印就是写出)
System.out以及System.err都是打印流的对象
演示
public static void main(String[] args) throws IOException {
// 打印流
PrintStream ps = new PrintStream("E:\\asd.txt");
// 写数据
ps.write("wqeqwe".getBytes());
// 打印到具体的位置--写出
ps.print(456123);
// 多了换行功能
ps.println(456123);
ps.println(456123);
}
合并流—SequenceInputStream
需要提供多个输入流对象,存储在Vector集合对象中,获取Enumeratio对象
最后构建成合并流对象, 合并–就是把所有的输入流的数据进行统一读取,注意输
入流的数据进行统一读取,注意输入流的编码,以及各式。
通过java合并视频—也可以合成其他类型文件例如txt,MP3等
不过没有后期处理可能会出现不可预料的问题
两个不同类型的文件也可以并流例如MP4文件与txt文件合并,但是若不妥善处理
也会出现乱码。
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.Enumeration;
import java.util.Vector;
public class hebing {
public static void main(String[] args) throws IOException {
// 提供输入流---提供待合并的数据
FileInputStream in = new FileInputStream("E:\\1.mp4");
FileInputStream in2 = new FileInputStream("E:\\2.mp4");
FileInputStream in3 = new FileInputStream("E:\\3.mp4");
// 把输入流对象添加到集合中
Vector<FileInputStream> v = new Vector<>();
v.add(in);
v.add(in2);
v.add(in3);
// 获取到Enumeration类型
// 把集合中的所有输入流对象存放到e对象中
Enumeration<FileInputStream> e=v.elements();
// 创建合并流对象--把含有输入流对象的e放到合并流对象中
SequenceInputStream sis = new SequenceInputStream(e);
// 文件字节输出流
FileOutputStream os = new FileOutputStream("D:\\合并完成.mp4");
// 通过合并流对象进行统一读取数据---合并
//自建缓冲区,控制传输速度
byte[]bs = new byte[1024*1024*10];
//写入
int len;
while((len=sis.read(bs))!=-1){
os.write(bs,0,len);
}
//关流
in.close();
in2.close();
in3.close();
sis.close();
//此时查看目标文件,已经完成合并,此功能只是合并三个视频文件,只能播放第一个文件内容
//若想观看全部视频内容,则需要另行处理
}
}
双向流—RandomAccessFile
可以指定文件的访问模式–rw(可读可写),操作数据时,下标会自动进行移动
也可以指定下标进行数据操作;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class shuangxiangliu {
public static void main(String[] args) throws IOException {
// 创建双向流对象--r--w---支持读和写
RandomAccessFile ra = new RandomAccessFile("E:\\1.txt", "rw");
// 写出数据--操作数据时会移动下标
/* ra.write("asdasd".getBytes());
// 设置数据操作的下标
ra.seek(0);
// 读取数据--当要读取数据时,下标已经移动到没有数据的位置
ra.read();
*/
// 也可以设置任意的位置;
ra.seek(5);
ra.write("asdasd".getBytes());
}
}
----–--**-–---**–-**-–---------------------*
序列化与反序列化
序列化:把要传输的对象以及相关信息(相关信息指属性)转换成对应的字节数组进行储存;
所有的静态属性,不能序列化;
若想将对象序列化,需要保证对象对应的类实现 Serializable 接口
不想某属性进行序列化,将该属性用 transient 修饰
用static或者trainsient修饰的属性,都不能被序列化
实现接口的这个类,如果没有指定序列化版本号(serialVersionUID),.java会在
底层算出当时的版本号,算出来的版本号就会随着对象一起序列化出去;反序列化
的时候,就会获取到序列化过来的版本号;再次计算此时类(类的属性和方法)
的版本号,反序列化时,会拿着序列化过来的版本号,和刚才计算好的版本号;如果两个
版本号相等,就反序列化成功,如果两个版本号不相等,就反序列化失败;
为了保证每次反序列化成功,就要在类中指定序列化版本号
(private static final long)修饰;
集合和映射对象都不能序列化,若想序列化,则遍历集合或映射逐个序列化其储存的对象;
若字节数组储存在硬盘----则称为持久化
反序列化:把字节数组,转回成相应的对象
创建一个类,实现Serializable接口
class person implements Serializable {
/**
* java默认提供的版本号
*/
private static final long serialVersionUID = -6364057872211697213L;
// 手动指定序列化版本号
//static final long serialVersionUID = 1;
private String name;
private int age;
//不想某属性进行序列化,将属性用 transient 修饰
transient double shengao;
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 static void main(String[] args) throws IOException {
// 创建对象
// 若想将对象序列化,需要保证对象对应的类实现 Serializable 接口
person p = new person();
//给对象属性赋值
p.setAge(10);
p.setName("asd");
// 开始进行序列化
ObjectOutputStream ot = new ObjectOutputStream(new FileOutputStream("p.data"));
// 写出对象,把对象进行序列化
ot.writeObject(p);
// 关流
ot.close();
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
public class xuliehuaIN {
public static void main(String[] args) throws IOException, ClassNotFoundException {
// 创建反序列化对象
ObjectInputStream in = new ObjectInputStream(new FileInputStream("p.data"));
//读入对象 ---保证获取的是传入的对象(转型)
person p = (person)in.readObject();
//关流
in.close();
//获取对象属性
System.out.println(p.getName());
}
}
关于Properties(配置文件)
可持久化的映射类,继承了Hashtable,键和值都应该是字符串
将要存储的内容,传输到配置文件中—配置文件后缀必须是properties
默认的编码是西欧编码,如果是中文,则按u16进行编码。
public class PropertiesDEmo {
public static void main(String[] args) throws FileNotFoundException, IOException {
// 创建对象
Properties p = new Properties();
// 添加元素--键和值都应为字符串
p.setProperty("name", "小明");
p.setProperty("gender", "不知道");
p.setProperty("age", "10");
// 将要存储的内容,传输到配置文件中---配置文件后缀必须是properties
// 第二个参数代表的是对文件的内容的解释;
p.store(new FileOutputStream("p.Preperties"), "此文件用于xxxxx");
}
}
加载配置文件
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
public class PropertiesDemo2 {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties p = new Properties();
// 加载指定的配置文件
p.load(new FileInputStream("p.Preperties"));
// 获取配置文件的内容
// 根据键获取值
System.out.println(p.getProperty("name"));
// 列出配置文件信息
p.list(System.out);
}
}
关于单元测试Junit
1、导入测试库–右击工程–build path----add Libeary—junit
2、测试方法时需在方法上添加@Test,右击方法名,run as junit
可以支持单元测试的方法:没有static修饰、没有返回值、没有参数;
但是也可以间接测试其他方法
例如
@Test//单元测试标识
public void m(){
System.out.println(1);
}
//若点击空白处运行,则所有的单元测试都执行
@Test
public void n(){
System.out.println(1);
// 间接测试
nn(22);
}
public void nn(int n){
System.out.println(1);
}
------------------------------------*–
关于断言----关键字assert
对程序结果进行预测性的判断
import java.util.Scanner;
public class asserttt {
public static void main(String[] args) {
// 输入一个整数
int num =new Scanner(System.in).nextInt();
// num右移一
num>>=1;
// 预测结果--如果预测正确代码继续执行,否则报错;
// 需要手动开启断言
//右击空白处,Run As ---Run configuration--Arguments标签--VM栏内填写 -ea 确定后开启
assert num<5:"结果应小于5";
System.out.println(num);
}
}