day22目录:
数据输入输出流
内存操作流
打印流
序列化流
随机访问流
Properties
22.03_IO流(数据输入输出流的概述和使用)(了解)
可以读取基本数据类型
A:数据输入输出流的概述
通过API查看
数据输入和输出流:
数据输入流: DataInputStream
数据输出流: DataOutputStream
特点: 可以写基本数据类型,可以读取基本数据类型
B:案例演示: 数据输入输出流的使用
public class MyTest {
public static void main(String[] args) throws IOException {
//数据输入输出流,此流最大的特点,就是能够读写基本数据类型
/* 数据输入流:
DataInputStream
数据输出流:
DataOutputStream*/
//wirteData();
//你怎么写的,你就怎么读取,顺序不要乱
DataInputStream in = new DataInputStream(new FileInputStream("a.txt"));
int num = in.readInt();
System.out.println(num);
boolean b = in.readBoolean();
System.out.println(b);
String s = in.readUTF();
System.out.println(s);
double v = in.readDouble();
System.out.println(v);
}
private static void wirteData() throws IOException {
DataOutputStream ds = new DataOutputStream(new FileOutputStream("a.txt"));
ds.writeInt(500);
ds.writeBoolean(true);
ds.writeUTF("hahaha");
ds.writeDouble(3.14);
ds.close();
}
}
22.04_IO流(内存操作流的概述和使用)(掌握)
A:内存操作流的概述
a:操作字节数组
ByteArrayOutputStream
ByteArrayInputStream
此流关闭无效,所以无需关闭
b:操作字符数组
CharArrayWrite
CharArrayReader
c:操作字符串
StringWriter
StringReader
B:案例演示: 内存操作流的使用
构造方法: public ByteArrayOutputStream()
public class MyTest {
public static void main(String[] args) throws IOException {
// 内存操作流: 不会关联文件,只是在内存中进行数据的读写,内存操作流,会自己在内存中维护了一个缓存,把数据维护在缓存中
/* a:
操作字节数组
ByteArrayOutputStream
ByteArrayInputStream
此流关闭无效,所以无需关闭
b:
操作字符数组
CharArrayWrite
CharArrayReader
c:
操作字符串
StringWriter
StringReader*/
// ByteArrayOutputStream
//ByteArrayInputStream
/* 此类实现了一个输出流,其中的数据被写入一个 byte 数组。
缓冲区会随着数据的不断写入而自动增长。
可使用 toByteArray () 和 toString () 获取数据。
关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
*/
/* 构造方法摘要
ByteArrayOutputStream()
创建一个新的 byte 数组输出流。
*/
//自己在内存中维护了一个字节数组充当缓存,你用他写入的数据,就会放到他维护的这个字节数组中, 缓冲区会随着数据的不断写入而自动增长
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write("aaa".getBytes());
bos.write("bbb".getBytes());
bos.write("ccc".getBytes());
//取出ByteArrayOutputStream 他所维护的那个字节数组
byte[] bytes = bos.toByteArray();
String s = new String(bytes);
// System.out.println(s);
//如果放的是,字符串的字节数据,你可以直接调用toString()
String s2 = bos.toString();
System.out.println(s2);
}
}
public class MyTest2 {
public static void main(String[] args) throws IOException {
/* 操作字节数组
ByteArrayOutputStream
ByteArrayInputStream*/
/* ByteArrayInputStream( byte[] buf)
创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。*/
byte[] bytes = "西部开源教育科技有限公司".getBytes();
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
byte[] bytes1 = new byte[1024];
int len = in.read(bytes1);
String s = new String(bytes1, 0, len);
System.out.println(s);
}
}
public class MyTest3 {
public static void main(String[] args) throws IOException {
//把多个文件合并成一个文件
//比如:我要把两首歌 合并成一首歌
FileInputStream in1 = new FileInputStream("许巍 - 蓝莲花.mp3");
FileInputStream in2 = new FileInputStream("许巍 - 曾经的你.mp3");
FileOutputStream allOut = new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\歌曲大连唱.mp3");
ArrayList<FileInputStream> list = new ArrayList<>();
list.add(in1);
list.add(in2);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] bytes = new byte[1024 * 8];
int len = 0;
for (FileInputStream in : list) {
while ((len = in.read(bytes)) != -1) {
bos.write(bytes, 0, len);
}
in.close();
}
//取出两首歌的字节数据
byte[] allBytes = bos.toByteArray();
ByteArrayInputStream bin = new ByteArrayInputStream(allBytes);
byte[] bytes2 = new byte[1024 * 8];
int len2 = 0;
while ((len2 = bin.read(bytes2)) != -1) {
allOut.write(bytes2, 0, len2);
allOut.flush();
}
allOut.close();
System.out.println("合并完毕");
}
}
public class MyTest4 {
public static void main(String[] args) throws IOException {
FileInputStream in1 = new FileInputStream("许巍 - 蓝莲花.mp3");
FileInputStream in2 = new FileInputStream("许巍 - 曾经的你.mp3");
FileOutputStream allOut = new FileOutputStream("C:\\Users\\ShenMouMou\\Desktop\\歌曲大连唱2.mp3");
ArrayList<FileInputStream> list = new ArrayList<>();
list.add(in1);
list.add(in2);
byte[] bytes2 = new byte[1024 * 8];
int len2 = 0;
for (FileInputStream in : list) {
while ((len2 = in.read(bytes2)) != -1) {
allOut.write(bytes2, 0, len2);
allOut.flush();
}
in.close();
}
allOut.close();
}
}
public class MyTest5 {
public static void main(String[] args) throws IOException {
/* b:
操作字符数组
CharArrayWrite
CharArrayReader*/
CharArrayWriter charArrayWriter = new CharArrayWriter();
charArrayWriter.write("abc");
charArrayWriter.write("abc");
charArrayWriter.write("abc");
charArrayWriter.write("abc");
String s = charArrayWriter.toString();
char[] chars = charArrayWriter.toCharArray();
String s1 = String.valueOf(chars);
System.out.println(s);
System.out.println(s1);
}
}
public class MyTest6 {
public static void main(String[] args) {
/* StringWriter
StringReader*/
StringWriter stringWriter = new StringWriter();
stringWriter.write("abc");
stringWriter.write("abc");
stringWriter.write("abc");
stringWriter.write("abc");
stringWriter.write("abc");
String s = stringWriter.toString();
System.out.println(s);
}
}
22.05_IO流(打印流的概述和特点以及作为Writer的子类使用))(理解)
A:打印流的概述
通过API查看
字节流打印流
字符打印流
B:打印流的特点
a: 打印流只能操作目的地,不能操作数据源(不能进行读取数据)
- b: 可以操作任意数据类型的数据 调用print() 方法可以写任意数据类型
- c: 如果我们启用自动刷新,那么在调用println、printf 或 format 方法中的一个方法的时候,会完成自动刷新
/**
通过以下构造创建对象 能够启动自动刷新 然后调用println、printf 或 format 方法中的一个方法的时候,会完成自动刷新
* public PrintWriter(OutputStream out, boolean autoFlush) 启动 自动刷新
* public PrintWriter(Writer out, boolean autoFlush) 启动自动刷新
*/
- d: 这个流可以直接对文件进行操作(可以直接操作文件的流: 就是构造方法的参数可以传递文件或者文件路径)
C:案例演示: PrintWriter作为Writer的子类使用
public class MyTest {
public static void main(String[] args) throws IOException {
//打印流:只能写,不是成对的,只有一个
//字符打印流 PrintWriter
//字节打印流 PrintStream
//自己创建出来的打印流,关联的是文件,所以你在调用println("abc"); 会输出到文件中
PrintStream printStream = new PrintStream("e.txt");
printStream.write("你好".getBytes());
printStream.println("abc");
printStream.println(100);
printStream.println(3.14);
//out “标准”输出流。此流已打开并准备接受输出数据。通常,此流对应于显示器
//System.out; 获取出的PrintStream 他所关联的设备是屏幕,所以你打印的数据,就会输出到屏幕上。
PrintStream out = System.out;
out.println(200);
out.write("hahah".getBytes());
}
}
//结果:上面四行在文件里,下面两行在控制台
22.06_IO流(PrintWriter实现自动刷新和换行)(理解)
A:案例演示:PrintWriter实现自动刷新和换行
PrintWriter pw = new PrintWriter(new FileWriter("printWriter2.txt") , true) ;
pw.println(true) ;
pw.println(100) ;
pw.println("中国") ;
public class MyTest2 {
public static void main(String[] args) throws FileNotFoundException {
//true 表示开启自动刷新
//如果启用了自动刷新,则只有在调用 println、printf 或 format 的其中一个方法时才可能完成此操作,
PrintWriter printWriter = new PrintWriter(new FileOutputStream("g.txt"), true);
printWriter.write("abc");
printWriter.write("abc");
printWriter.write("abc");
printWriter.write("abc");
printWriter.flush();
printWriter.println("abc");
printWriter.println("abc");
printWriter.println("abc");
printWriter.println("abc");
printWriter.println("abc");
printWriter.close();
}
}
//结果:全部写在文件里
22.07_IO流(打印流复制文本文件)(理解)
A:案例演示: 打印流复制文本文件
分析:
- 这个打印流只能进行写数据,不能进行读取数据,
那么我们应该找一个可以读取文本文件中的的数据的流对象进行读取操作.
- 而我们非常喜欢高效的流对象,于是我们可以使用BufferedReader进行读取数据.
*
public class MyTest3 {
public static void main(String[] args) throws IOException {
/* A:
案例演示:
打印流复制文本文件*/
BufferedReader reader = new BufferedReader(new FileReader("name.txt"));
PrintWriter out = new PrintWriter(new FileOutputStream("name2.txt"), true);
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
out.println(line);
}
reader.close();
out.close();
}
}
22.08_IO流(标准输入输出流概述和输出语句的本质)(理解)
A:标准输入输出流概述
在System这个类中存在两个静态的成员变量:
-
- public static final InputStream in: 标准输入流, 对应的设备是键盘
- public static final PrintStream out: 标准输出流 , 对应的设备就是显示器
System.in的类型是InputStream.
System.out的类型是PrintStream是OutputStream的孙子类FilterOutputStream 的子类.
B:案例演示: 输出语句的本质
22.09_IO流(二种方式实现键盘录入)(理解)
A:Scanner
B:BufferedReader的readLine方法。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
public class demo {
public static void main(String[] args) throws IOException {
// “标准”输入流。此流已打开并准备提供输入数据。通常,此流对应于键盘输入
/* InputStream in = System.in; //BufferedInputStream
System.out.println(in);
Scanner scanner = new Scanner(System.in);*/
//键盘录入的第二种方式
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.println("请输入内容");
//自己定义一个结束的标记 886
String s = reader.readLine();
if ("886".equals(s)) {
break;
}
System.out.println(s);
}
}
}
public class MyTest {
public static void main(String[] args) throws FileNotFoundException {
/* Scanner(File source)
构造一个新的 Scanner,它生成的值是从指定文件扫描的。*/
Scanner scanner = new Scanner(new File("demo.java"));
PrintWriter printWriter = new PrintWriter("demo2.java");
while (scanner.hasNextLine()) {
String s = scanner.nextLine();
//System.out.println(s);
printWriter.println(s);
printWriter.flush();
}
scanner.close();
printWriter.close();
}
}
22.10_IO流(输出语句用字符缓冲流改进)(理解)
A:案例演示: 输出语句用字符缓冲流改进
/**
* 获取System下的in成员变量
*/
InputStream in = System.in ;
/**
* in是一个字节输入流对象,那么我们就可以通过这个字节输入流对象进行读取键盘录入的数据.
* 那么我们既然要读取数据,之前我们讲解了两种读取数据的方式:
* 1. 一次读取一个字节
* 2. 一次读取一个字节数组
* 那么我们在这个地方使用那种读取方式. 经过分析,这两种读取方式都不太合适.因为数据是客户通过键盘录入
* 进来的,而我们希望直接读取一行数据. 而既然要读取一行数据,那么我们就需要使用readLine方法,而这个方法
* 是属于BufferedReader的方法,而我们就需要创建一个BufferedReader对象进行读取数据.而我们这in有属于
* 字节流,而创建BufferedReader对象的时候需要一个字符流,而我们就需要将这个字节流转换成字符流,那么既然
* 要对其进行转换,那么就需要使用转换流. 需要使用InputStreamReader
*/
22.11_IO流(随机访问流概述和写出数据)(掌握)
A:随机访问流概述
RandomAccessFile概述 最大特点 能读能写
RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。
支持对随机访问文件的读取和写入。
RandomAccessFile的父类是Object , 这个流对象可以用来读取数据也可以用来写数据.可以操作任意数据类型的数据.
我们可以通过getFilePointer方法获取文件指针,并且可以通过seek方法设置文件指针
B:案例演示: 随机访问流写出数据
public class MyTest {
public static void main(String[] args) throws IOException {
//RandomAccessFile 这个流最大的特点,有文件指针指针,可以进行断点,还有一个就是能读能写
//此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;
// RandomAccessFile(File file, String mode)
// 创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
//你怎么写的你就怎么读,顺序不要乱
RandomAccessFile in = new RandomAccessFile(new File("a.txt"), "rw");
boolean b = in.readBoolean();
//获取文件指针的位置
long filePointer = in.getFilePointer();
System.out.println(filePointer); //1
double v = in.readDouble();
filePointer = in.getFilePointer();
System.out.println(filePointer); //9
int i = in.readInt();
filePointer = in.getFilePointer();
System.out.println(filePointer); //13
String s = in.readUTF();
filePointer = in.getFilePointer();
System.out.println(filePointer); //21
//设置文件的指针位置
in.seek(13);
s = in.readUTF();
System.out.println(s);
System.out.println(b);
System.out.println(v);
System.out.println(i);
System.out.println(s);
}
private static void writeData() throws IOException {
RandomAccessFile out = new RandomAccessFile(new File("a.txt"), "rw");
out.writeBoolean(false);
out.writeDouble(3.14);
out.writeInt(100);
/* 首先,把两个字节从文件的当前文件指针写入到此文件,
类似于使用 writeShort 方法并给定要跟随的字节数。此值是实际写出的字节数,*/
out.writeUTF("呵呵");
out.close();
}
}
public class MyTest3 {
public static void main(String[] args) throws IOException {
//模拟断点复制
File file = new File("歌曲大连唱2.mp3");
File file2 = new File("C:\\Users\\ShenMouMou\\Desktop\\歌曲大连唱333.mp3");
RandomAccessFile in = new RandomAccessFile(file, "rw");
RandomAccessFile out = new RandomAccessFile(file2, "rw");
//继续:判断目标文件是否还存在,如果不存在,就从头复制,如果存在,获取上次记录的断点的位置,继续复制
if (!file2.exists()) {
in.seek(0);
out.seek(0);
}
//如果文件存在,就从上次的断点位置,开始复制
//读取上次的断点位置
BufferedReader reader = new BufferedReader(new FileReader("config.txt"));
String seek = reader.readLine();
//设置从哪个位置开始复制。
in.seek(Long.parseLong(seek));
out.seek(Long.parseLong(seek));
byte[] bytes = new byte[1];
int len = 0;
int i = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
//模拟暂停
/* i = i += 2;
if (i > 100000) {
//获取暂停后文件的指针位置
long filePointer = in.getFilePointer();
//把这个文件指针的位置,保存到一个配置文件里面
PrintWriter pw = new PrintWriter(new FileOutputStream("config.txt"), true);
pw.println(filePointer);
break;
}*/
}
in.close();
out.close();
}
}
22.12_IO流(随机访问流读取数据和操作文件指针)(了解)
A:案例演示: 随机访问流读取数据和操作文件指针
22.13_IO流(序列化流和反序列化流的概述和使用)(理解)
A:序列化流的概述
所谓的序列化:就是把对象通过流的方式存储到文件中.注意:此对象 要重写Serializable 接口才能被序列化
反序列化:就是把文件中存储的对象以流的方式还原成对象
序列化流: ObjectOutputStream
反序列化流: ObjectInputStream
像这样一个接口中如果没有方法,那么这样的接口我们将其称之为标记接口(用来给类打标记的,相当于猪肉身上盖个章)
一个对象可以被序列化的前提是这个对象对应的类必须实现Serializable接口
B:案例演示: 对象序列化和反序列化的基本使用
//Serializable 并没有任何抽象方法,那这种接口,我们称之为标记接口。
//Cloneable 那这种接口,我们称之为标记接口
public class Student implements Serializable {
//实现Serializable接口之后,最好再给一个serialVersionUID就行。
private static final long serialVersionUID = -5332899031890796073L;
public String name;
//关键字 transient 排除某个字段不会被序列化
private transient int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 MyTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化: 将内存中的Java对象,保存文件中。
//反序列化 :将文件中的Java对象,读取回内存中
/* 序列化流:
ObjectOutputStream
反序列化流:
ObjectInputStream*/
//wirteData();
readObj();
//浅克隆:clone() 浅克隆,你克隆的这个对象,里面维护了另外一个类的对象,你克隆时,他只会克隆你维护的那个对象的地址值,并不会把你维护的那个对象克隆一份
//深克隆:采用序列化列 来进行深克隆
}
private static void readObj() throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("student.txt"));
Student student = (Student) in.readObject();
String name = student.getName();
int age = student.getAge();
System.out.println(name);
System.out.println(age);
}
private static void wirteData() throws IOException {
Student student = new Student("张三", 23);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student.txt"));
//NotSerializableException 我们要把一个类的对象,要成功的序列化,对这个类有一个要求,要求这个类必须实现一个Serializable这个序列化接口
out.writeObject(student);
out.close();
}
}
class Dog {
DogFood dogFood;
}
class DogFood {
}
22.14_IO流(如何解决序列化时候的黄色警告线问题)(理解)
A:案例演示: 解决序列化时候的黄色警告线问题
- 我们的一个类可以被序列化的前提是需要这个类实现Serializable接口,就需要给这个类添加一个标记.
- 在完成序列化以后,序列化文件中还存在一个标记,然后在进行反序列化的时候,
会验证这个标记和序列化前的标记是否一致,如果一致就正常进行反序列化,如果
- 不一致就报错了. 而现在我们把这个类做了修改,将相当于更改了标记,而导致这两个标记不一致,就报错了.
-
- 解决问题: 只要让这个两个标记一致,就不会报错了吧
- 怎么让这两个标记一致呢? 不用担心,很简单,难道你们没有看见黄色警告线吗? alt+enter, 生成出来
private static final long serialVersionUID = -7602640005373026150L;
//Serializable 并没有任何抽象方法,那这种接口,我们称之为标记接口。
//Cloneable 那这种接口,我们称之为标记接口
public class Student implements Serializable {
//实现Serializable接口之后,最好再给一个serialVersionUID就行。
private static final long serialVersionUID = -5332899031890796073L;
public String name;
//关键字 transient 排除某个字段不会被序列化
private transient int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
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 MyTest3 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/* Student student1 = new Student("张三", 23);
Student student2 = new Student("李四", 24);
Student student3 = new Student("王五", 25);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student2.txt"));
//NotSerializableException 我们要把一个类的对象,要成功的序列化,对这个类有一个要求,要求这个类必须实现一个Serializable这个序列化接口
out.writeObject(student1);
out.writeObject(student2);
out.writeObject(student3);
out.close();*/
ObjectInputStream in = new ObjectInputStream(new FileInputStream("student2.txt"));
Student student = (Student) in.readObject();
String name = student.getName();
int age = student.getAge();
System.out.println(name);
System.out.println(age);
}
private static void readObj() throws IOException, ClassNotFoundException {
}
}
public class MyTest4 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
/* Student student1 = new Student("张三", 23);
Student student2 = new Student("李四", 24);
Student student3 = new Student("王五", 25);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("student2.txt"));
ArrayList<Student> list = new ArrayList<>();
list.add(student1);
list.add(student2);
list.add(student3);
out.writeObject(list);
out.close();*/
ObjectInputStream in = new ObjectInputStream(new FileInputStream("student2.txt"));
ArrayList<Student> list = (ArrayList<Student>) in.readObject();
Student student = list.get(2);
System.out.println(student.getName());
}
}
22.15_IO流(如何让对象的成员变量不被序列化)(理解)
A:案例演示: 如何让对象的成员变量不被序列化
使用transient关键字声明不需要序列化的成员变量
private transient int age ;// 可以阻止成员变量的序列化使用transient
22.16_IO流(Properties的概述和作为Map集合的使用)(掌握)
A:Properties的概述
查看API
Properties 类表示了一个持久的属性集。
Properties 可保存在流中或从流中加载。
属性列表中每个键及其对应值都是一个字符串。
Properties父类是Hashtable
- 属于双列集合,这个集合中的键和值都是字符串 Properties不能指定泛型
B:案例演示: Properties作为Map集合的使用
public class MyTest {
public static void main(String[] args) {
// 属性集合 键值一般存储String类型
//Properties
Properties properties = new Properties();
/* properties.put("username", "张三");
properties.put("passwrod", "123456");
String username = (String) properties.get("username");
System.out.println(username);
*/
//建议使用他自己特有的方法,放存取数据
properties.setProperty("username", "张三");
properties.setProperty("password", "123456");
String username = properties.getProperty("username");
String password = properties.getProperty("password");
System.out.println(username);//张三
System.out.println(password);//123456
//参数2,默认值,当这个键没有找到对应的值,就返回默认值
String password2 = properties.getProperty("password55", "56987");
System.out.println(password2);//56987
}
}
22.17_IO流(Properties的特殊功能使用)(掌握)
A:Properties的特殊功能
public Object setProperty(String key,String value)
public String getProperty(String key)
public Set<String> stringPropertyNames()
B:案例演示: Properties的特殊功能
public class MyTest2 {
public static void main(String[] args) throws IOException {
//username=张三
//password=123456
LinkedHashMap<String, String> map = new LinkedHashMap<>();
map.put("username", "张三");
map.put("password", "123456");
Set<Map.Entry<String, String>> entries = map.entrySet();
BufferedWriter writer = new BufferedWriter(new FileWriter("user.properties"));
for (Map.Entry<String, String> en : entries) {
String key = en.getKey();
String value = en.getValue();
writer.write(key + "=" + value);
writer.newLine();
writer.flush();
}
writer.close();
}
}
public class MyTest3 {
public static void main(String[] args) throws IOException {
LinkedHashMap<String, String> map = new LinkedHashMap<>();
BufferedReader reader = new BufferedReader(new FileReader("user.properties"));
while (true) {
String s = reader.readLine();
if (s == null) {
break;
}
String[] split = s.split("=");
map.put(split[0], split[1]);
}
System.out.println(map);
}
}
22.18_IO流(Properties的load()和store()功能)(掌握)
A:Properties的load()和store()功能
Properties和IO流进行配合使用:
- public void load(Reader reader): 读取键值对数据把数据存储到Properties中
- public void store(Writer writer, String comments)把Properties集合中的键值对数据写入到文件中, comments注释
B:案例演示
Properties的load()和store()功能
public class MyTest4 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
//建议使用他自己特有的方法,放存取数据
properties.setProperty("username", "张三");
properties.setProperty("password", "123456");
//把属性集合中的键值对数据,存到文本文件中
properties.store(new FileOutputStream("user2.properties"), null);
}
}
public class MyTest5 {
public static void main(String[] args) throws IOException {
//Properties 读取配置文件中的数据到集合中,
// 对这个配置文件的要求,这个配置文件的数据格式 键值关系的数据,键和值使用=拼接 文件后缀名 .properties
Properties properties = new Properties();
properties.load(new FileReader("demo.properties"));
System.out.println(properties);
}
}
22.19_IO流(判断文件中是否有指定的键如果有就修改值的)(掌握)
A:案例演示
需求:我有一个文本文件,我知道数据是键值对形式的,但是不知道内容是什么。
请写一个程序判断是否有“lisi”这样的键存在,如果有就改变其值为”100”
分析:
- a: 把文本文件中的数据加载到Properties集合中
- b: 判断这个集合中是否有"lisi"这个键
- 如果有直接修改其值为100
- c: 把集合中的数据再次存储到文本文件中
22.19_IO流(SequenceInputStream)(掌握)
A:案例需求:将a.txt和b.txt两个文本文件的内容合并到c.txt
public class MyTest {
public static void main(String[] args) throws IOException {
//SequenceInputStream 表示其他输入流的逻辑串联。
/* 它从输入流的有序集合开始,
并从第一个输入流开始读取,直到到达文件末尾
,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。*/
FileInputStream in = new FileInputStream("user.properties");
FileInputStream in2 = new FileInputStream("user2.properties");
/* SequenceInputStream(InputStream s1, InputStream s2)
通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),以提供从此 SequenceInputStream 读取的字节。*/
SequenceInputStream allIn = new SequenceInputStream(in, in2);
FileOutputStream out = new FileOutputStream("hehe.properties");
byte[] bytes = new byte[1024];
int len = 0;
while ((len = allIn.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();
}
allIn.close();
}
}
B:案例需求:采用SequenceInputStream来改进
C:作业:将一个music.mp3文件,拆分成多个小文件,再将多个小文件,合并成一个mp3文件
D:SequenceInputStream
表示其他输入流的逻辑串联。
它从输入流的有序集合开始,
并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,
依次类推,直到到达包含的最后一个输入流的文件末尾为止
a:构造方法
SequenceInputStream(InputStream s1, InputStream s2)
通过记住这两个参数来初始化新创建的 SequenceInputStream(将按顺序读取这两个参数,先读取 s1,然后读取 s2),
以提供从此 SequenceInputStream 读取的字节。
b:构造方法
SequenceInputStream(Enumeration<? extends InputStream> e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。
public class MyTest2 {
public static void main(String[] args) throws FileNotFoundException {
FileInputStream in = new FileInputStream("user.properties");
FileInputStream in2 = new FileInputStream("user2.properties");
FileInputStream in3 = new FileInputStream("user2.properties");
SequenceInputStream allIn = new SequenceInputStream(in, in2);
SequenceInputStream allIn2 = new SequenceInputStream(allIn, in3);
}
}
public class MyTest3 {
public static void main(String[] args) throws FileNotFoundException {
/* SequenceInputStream(Enumeration < ? extends InputStream > e)
通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。*/
FileInputStream in = new FileInputStream("user.properties");
FileInputStream in2 = new FileInputStream("user2.properties");
FileInputStream in3 = new FileInputStream("user2.properties");
Vector<FileInputStream> vector = new Vector<>();
vector.add(in);
vector.add(in2);
vector.add(in3);
Enumeration<FileInputStream> elements = vector.elements();
SequenceInputStream allIn = new SequenceInputStream(elements);
}
}
22.20_day22总结
补充: