2020/8/21
1.Properties类
1.概述
Properties叫属性集,是Hashtable的子类,属于双列集合,这个集合键值对都是字符串类型,不需要规定泛型,我们通常使用与流相关的变量
2.构造函数
方法 | 说明 |
---|---|
public Properties | 创建一个空的属性列表 |
3.常用方法
方法 | 说明 |
---|---|
Object setProperty(String key,String value) | 添加键值对 |
String getProperty(String key) | 根据键获取值 |
stringPropertyNames() | 获取所有的键 |
load(输入流) | 把文件中的键值对数据读到集合中 |
store(输出流,String comments) | 把集合中的键值对保存到文件中 |
-
专门存放键值对的文件· abc.properties
-
键值对存放中间分隔符是等号或者冒号
-
后缀位properties的文件是配置文件, #是注释
-
集合相关方法
import java.util.Properties; import java.util.Set; public class Test01 { public static void main(String[] args) { Properties p = new Properties(); p.setProperty("username","柳岩"); p.setProperty("password","123456"); String s = p.getProperty("username"); System.out.println(s); Set<String> set = p.stringPropertyNames(); System.out.println(set); } }
-
配置文件自己会进行检查,不允许重名
-
IO相关方法
-
读数据
import java.io.FileReader; import java.io.IOException; import java.util.Properties; public class Test03 { public static void main(String[] args) throws IOException { Properties p = new Properties(); FileReader fr = new FileReader("day11\\abc.properties"); //会把文件中的键值对读取到集合中 p.load(fr); String font = p.getProperty("font"); String color = p.getProperty("color"); System.out.println("字体大小为:"+font); System.out.println("字体颜色为"+color); } }
-
-
写数据
import java.io.FileWriter; import java.io.IOException; import java.util.Properties; public class Test02 { public static void main(String[] args) throws IOException { Properties p = new Properties(); p.setProperty("font","16"); p.setProperty("color","white"); FileWriter fw = new FileWriter("day11\\abc.properties"); //store() :把集合中的键值对写出到文件中 //第一个参数输出流,第二个参数输出备注 p.store(fw,"comments"); fw.close(); } }
2.ResourceBundle工具类
1.作用
- 可以在某些情况下,替代·Properties完成读取键值对
- 前提:
- 文件必须是配置文件,以properties为后缀名
- 文件必须放在src这个目录下
- 前提:
2.创建对象
-
静态方法:
// 使用指定的基本名称,默认语言环境和调用者的类加载器获取资源包。 static ResourceBundle getBundle(String baseName);
3.获取方法
String getString(String key)//根据键获取值
-
示例代码
import java.io.FileReader; import java.io.IOException; import java.util.Properties; import java.util.ResourceBundle; import java.util.Set; public class Test04 { public static void main(String[] args) throws IOException { /* Properties p = new Properties(); FileReader fr = new FileReader("day11\\abc.properties"); p.load(fr); Set<String> set = p.stringPropertyNames(); for (String s : set) { String str = p.getProperty(s); System.out.println(s+"="+str); }*/ ResourceBundle rb = ResourceBundle.getBundle("abc"); String font = rb.getString("font"); System.out.println(font); String color = rb.getString("color"); System.out.println(color); } }
3.缓冲流
1.介绍
-
缓冲功能就是提高效率
-
普通流的使用效率比较低,java提供四个缓冲流提高四个普通流的效率
-
字符串缓冲区、Stringbulider
-
之前字符流有的方法缓冲流都有
-
缓冲输出流都是先把数据输出到缓冲区
FileOutputStream --> BufferedOutputStream FileInputStream --> BufferedInputStream FileWriter --> BufferedWriter FileReader --> BufferedReader
2.字节缓冲流
-
构造方法
public BufferedInputStream(InputStream in) : 创建一个新的缓冲输入流。 public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
-
缓冲效果显示
- 字节缓冲流作用就只是提高效率,没有什么特殊功能。
import java.io.*; public class Test05 { public static void main(String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day11\\提醒.txt")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11\\提醒.txt")); bis.close(); bos.close(); } }
3.字符缓冲流
-
构造方法
public BufferedReader(Reader in):创建一个新的缓冲输入流 public BufferedWriter(Writer out):创建一个新的缓冲输出流
-
方法演示
- 之前字符流有的方法缓冲流都有
public class Test06 { public static void main(String[] args) throws IOException { //public BufferedReader(Reader in) :创建一个新的缓冲输入流。 BufferedReader br = new BufferedReader(new FileReader("day11\\123.txt")); //public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。 BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\123.txt")); /* 方法 字符缓冲输入流 输入一个字符 输入一个字符数组 字符缓冲输出流 输出一个字符 输出一个字符数组 输出一个字符数组的一部分 输出一个字符串 */ } }
-
字符缓冲流中特有的方法
- 两个特殊方法
BuffeeredReader: public String readLIine()://都一行文字 //读取一整行,如果读到了结尾返回null BufferedWriter: public void newLine() ://写换行,由系统属性定义符号 //兼容不同的系统
-
示例代码
- 读取一行
import java.io.*; public class Test07 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("day11\\提醒.txt")); String s = br.readLine(); System.out.println(s); System.out.println(br.readLine()); System.out.println(br.readLine()); //如果读到了末尾 文件会返回null System.out.println(br.readLine()); br.close(); } }
-
换行
import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; public class Test08 { public static void main(String[] args) throws IOException { BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\提醒.txt")); bw.write("加一行,"); bw.write("看看换行吗?"); bw.newLine();//换行 bw.write("哈哈"); bw.close(); } }
-
缓冲流的小结
字节缓冲流 没有特殊的方法,只是提高了效率 字符缓冲流 第一个功能是提高效率 特殊功能: 读取一整行readLine() 写出换行符newLine()
-
练习题
- 需求:排序
- 排序前文件里面是乱序的,排序后,文件里面是123456789
3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉 以咨之,然后施行,必得裨补阙漏,有所广益。 8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其 咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。 4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之, 必能使行阵和睦,优劣得所。 2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不 宜偏私,使内外异法也。 1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外 者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以 塞忠谏之路也。 9.今当远离,临表涕零,不知所言。 6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣 以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。 7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。 今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛 下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。 5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息 痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
-
代码编写
import java.io.*; import java.util.TreeSet; public class Test09 { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new FileReader("day11\\出师表.txt")); TreeSet<String> set = new TreeSet<>(); String s; while ((s = br.readLine()) != null) { set.add(s); } System.out.println(set); BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\出师表.txt")); for (String s1 : set) { bw.write(s1); bw.newLine(); } br.close(); bw.close(); } }
4.转换流
1.编码表介绍
2.输入转换流InputStreamReader类
-
构造方法
InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。 InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流
-
代码演示
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; public class Test10 { public static void main(String[] args) throws IOException { InputStreamReader isr = new InputStreamReader(new FileInputStream("day11\\出师表.txt")); int read = isr.read(); System.out.println(read); System.out.println((char)read); int read2 = isr.read(); System.out.println(read2); System.out.println((char)read2); } }
3.输出转换流OutputStreamWriter类
-
构造方法
OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。 OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流
-
代码演示
import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; public class Test11 { public static void main(String[] args) throws IOException { OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11\\出师表.txt"), "GBK"); osw.write("中国"); osw.close(); } }
-
总结
转换流的本质也是字符流,所以可以调用字符流的方法 转换流用于指定编码表的情况 在idea上普通流不能指定码表,默认都是UTF-8
4.练习:把UTF-8文件转成GBK
把’'出师表.txt"UTF-8编码的文件 变成了 ‘’出师表2.txt‘’GBK编码的文件
import java.io.*;
public class Test12 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("day11\\出师表.txt");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11\\出师表2.txt"),"GBK");
int read ;
while((read = fr.read())!=-1){
osw.write(read);
}
fr.close();
osw.close();
InputStreamReader isr = new InputStreamReader(new FileInputStream("day11\\出师表2.txt"),"GBK");
while ((read = isr.read())!=-1){
System.out.print((char)read);
}
isr.close();
}
}
5.序列流
1.概述
-
序列流可以操作对象。
-
序列化:把对象从内存保存到文件中。
-
反序列化:把对象从文件读取到内存中。
2.ObjectOutputStream类
-
序列化流,对象输出流
-
构造方法
public ObjectOutputStream(OutputStream out) : 创建一个指定的ObjectOutputStream
-
写出对象方法
public final void writeObject (Object obj) : 将指定的对象写出。
-
常见的两个疑惑
- Serializable这个接口我们称为是标记型接口,这个接口中没有任何的方法。
- 输出的对象在电脑中显示是乱码,这是正常的。因为电脑根本就没有查看对象的方式。
- 序列化把对象保存在硬盘中
-
代码演示
import java.io.Serializable; public class Student implements Serializable{ String name; int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } } import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class Test13 { public static void main(String[] args) throws IOException{ ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\123.txt")); Student stu = new Student("柳岩", 36); oos.writeObject(stu); oos.close(); } }
3.ObjectInputSream类
-
反序列化流,对象输入流
-
构造方法
public ObjectInputStream(InputStream in) : 创建一个指定的ObjectInputStream
-
读取对象方法
public final Object readObject() : 读取一个对象。
-
代码演示
import java.io.*; public class Test14 { public static void main(String[] args) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\123.txt")); Object o = ois.readObject(); Student stu = (Student)o; System.out.println(stu.toString()); ois.close(); } }
4.对象操作的作用
- 对象操作流作用就是输出输入对象类型,别的流都是只能操作文本。
5.对象操作的小知识点
-
transient关键字
-
transient表示瞬态,被瞬态修饰的成员变量不会被序列化。
private transient int age;
-
-
serialVersionUID问题
- 每个类都有一个UID编号,每次修改类编号都会随机改变,如果类在序列化和反序列化之间编号不同,反序列化会失败。如果中间要修改这个类,需要在序列化之前手动指定一个UID.
import java.io.Serializable;
public class Student implements Serializable {
public static final long serialVersionUID = 2134186281837358146L;
String name;
String sex;
int age;
public Student() {
}
public Student(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class Test5_1 {
public static void main(String[] args) throws IOException {
Student stu = new Student("迪丽热巴","女",18);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\test5_1.txt"));
oos.writeObject(stu);
oos.close();
}
}
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Objects;
public class Test5_2 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\test5_1.txt"));
Object o = ois.readObject();
Student s = (Student) o;
System.out.println(s);
}
}
-
序列化多个对象
- readObject()方法在读取到末尾的时候会直接抛出EOFException,不建议读取多次。
- 如果想要保存多个对象,建议把多个对象放在一起一次保存(用集合存储)。
import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.ArrayList; public class Test03 { public static void main(String[] args) throws IOException { //ObjectOutputStream序列化流,对象输出流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\123.txt")); //创建对象 Student s1 = new Student("柳岩",38); Student s2 = new Student("崔航",28); //放在集合中 ArrayList<Student> list = new ArrayList<>(); list.add(s1); list.add(s2); //输出任意类型对象 oos.writeObject(list); //关流 oos.close(); } } import java.io.FileInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.util.ArrayList; @SuppressWarnings("all")//带着泛型的转型都有警告,用此语句来消除 public class Test04 { public static void main(String[] args) throws IOException, ClassNotFoundException { //对象输入流 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\123.txt")); //读取对象 Object obj = ois.readObject(); //向下转型 ArrayList<Student> list = (ArrayList<Student>)obj; //打印 System.out.println(list); //关流 ois.close(); } }
6.打印流
1.概述
- 打印流帮助程序把数据用打印的方式来输出。
2.构造方法
public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流。
3.代码演示
import java.io.FileNotFoundException;
import java.io.PrintStream;
public class Test01 {
//打印流
public static void main(String[] args) throws FileNotFoundException {
//创建对象
PrintStream ps = new PrintStream("day11\\123.txt");
//输出
//以打印的方式来输出,你写啥就是啥
ps.print(97);
ps.print(98);
ps.print(1);
ps.print(3.14);
ps.print("哈哈哈");
ps.println('a');
ps.println('b');
ps.println('c');
//在控制台输出数据
System.out.println();
//输出语句使用ps这个对象作为打印流
System.setOut(ps);
System.out.println("柳岩");
//关流
ps.close();
}
}
7.装饰设计模式
1.概述
如果想要对类进行增强,且不想使用继承的情况下。就可以使用装饰设计模式。
前提:
被装饰类必须实现接口。
2.装饰设计模式写法
-
用装饰类实现和被装饰类同样的接口。
-
在装饰类中定义被装饰类的对象,使用构造方法传入对象。
-
需要增强的方法自己去编写。
-
不需要增强的方法调用被装饰类原来的方法。
3.代码演示
package com.itheima_05;
public interface Star {
//唱跳
void singAndDance();
//rap
void rap();
}
//被装饰类
public class CaiXuKun implements Star{
//功能
public void singAndDance(){
System.out.println("唱跳");
}
public void rap(){
System.out.println("鸡你太美~");
}
}
//装饰类 增强类
public class BufferedCaiXuKun implements Star {
//定义成员变量
CaiXuKun cxk;
//构造方法
public BufferedCaiXuKun(CaiXuKun cxk) {
this.cxk = cxk;
}
@Override
//增强的方法
public void singAndDance() {
System.out.println("唱青藏高原");
System.out.println("跳广场舞");
}
@Override
public void rap() {
cxk.rap();
}
}
public class Test02{
public static void main(String[] args) {
//创建增强类对象
BufferedCaiXuKun bc = new BufferedCaiXuKun(new CaiXuKun());
//调用方法
bc.rap();
bc.singAndDance();
}
}
4.开发的原则
开发的原则:
高内聚,低耦合
内聚:自己独立完成功能的能力。
耦合:代码和代码之间的依赖。
继承有一个缺点就是会提高类的耦合。
8.commons-io包
1.概述
commons-io是一个第三方jar包。
commons-io是Apache基金组织开发的开源工具,这个工具不在JDK里,使用的时候需要单独导入jar包。
2.使用方式
- 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/
- 把commons-io-2.6.jar包复制到指定的Module的lib目录中
- 将commons-io-2.6.jar加入到classpath【右键–add as Library–选择到模块中】
3.方法
-
IOUtils类中
- public static int copy(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以下)
- public static long copyLarge(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以上)
-
FileUtils类中
- public static void copyFileToDirectory(final File srcFile, final File destFile) //复制文件到另外一个目录下
- public static void copyDirectoryToDirectory( file1 , file2 );//复制file1目录到file2位置
package com.itheima_06; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import java.io.*; public class Test01 { public static void main(String[] args) throws IOException { //IOUtils //public static int copy(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以下) //IOUtils.copy(new FileInputStream("day11\\出师表.txt"),new FileOutputStream("C:\\Users\\jin\\Desktop\\出师表.txt")); //public static long copyLarge(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以上) //IOUtils.copyLarge(new FileInputStream("day11\\出师表.txt"),new FileOutputStream("C:\\Users\\jin\\Desktop\\出师表.txt")); //FileUtils //public static void copyFileToDirectory(final File srcFile, final File destFile) //复制文件到另外一个目录下 //FileUtils.copyFileToDirectory(new File("C:\\Users\\jin\\Desktop\\1234.txt"),new File("C:\\Users\\jin\\Desktop\\day11")); //public static void copyDirectoryToDirectory( file1 , file2 );//复制file1目录到file2位置 FileUtils.copyDirectoryToDirectory(new File("C:\\Users\\jin\\Desktop\\repositorys"),new File("C:\\Users\\jin\\Desktop\\day11")); } }
其实我们现在所能想到的功能,都已经有人实现了。
现阶段学习的很多知识点都是原理并不是应用。
9.IO流的异常处理
-
JDK7之前
package com.itheima_06; import java.io.*; public class Test02 { public static void main(String[] args){ OutputStreamWriter osw = null; try { //创建转换流对象 osw = new OutputStreamWriter(new FileOutputStream("day11"), "GBK"); //输出汉字 osw.write("中国"); }catch (IOException e){ }finally { //一定会执行的代码 try { //关流 if(osw != null) { osw.close(); } }catch (IOException e){ } } } }
-
JDK7之后
不需要调用关流方法
try(创建流对象;创建流对象){ 其他代码 }catch(异常类型 异常对象){ }
不需要调用关流方法,这个写法代码会自动帮我们关流
```java
package com.itheima_06;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class Test03 {
public static void main(String[] args) throws IOException {
//JDK7之后trycatch可以帮我们关流
try(OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11\\123.txt"),"GBK")){
osw.write("中国");
}catch (IOException e){
//异常处理
}
}
}