1、Properties
Properties是Hashtable的子类,也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串。是集合和IO技术相结合的集合容器
该对象的特点:可以用于键值对形式的配置文件。
Properties的一些常用的方法
Object setProperty(String key,String value):调用Hashtable的put方法,设置键值对 String getProperty(String key):通过指定的键获取值。 Set<String> stringPropertyNames:获取集合中所有的键 Load(InputStream in): 从输入流中读取属性列表(键和元素对)。 Load(Reader reader): 按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)。 Store(OutputStream out,String comments): Store(Writer writer,String comments) |
例如:
package com.itheima.file; import java.util.Properties; public class PropertiesDemo1 { public static void main(String[] args) { //创建一个Properties集合对象 Properties prop=new Properties(); //往prop中添加元素 prop.setProperty("1","黑马_1"); prop.setProperty("2","黑马_2"); prop.setProperty("3","黑马_3"); //获取指定键的值 String value=prop.getProperty("1"); //打印值 System.out.println(value); } } |
运行结果:黑马_1
问题:怎样获取所有集合中的元素呢?
package com.itheima.file; import java.util.Properties; import java.util.Set; public class PropertiesDemo1 { public static void main(String[] args) { //创建一个Properties集合对象 Properties prop=new Properties(); //往prop中添加元素 prop.setProperty("1","黑马_1"); prop.setProperty("2","黑马_2"); prop.setProperty("3","黑马_3"); //获取集合中所有的键 Set<String>set=prop.stringPropertyNames(); //利用增强for循环输出键值 for(String str:set){ System.out.println(str+"::"+prop.getProperty(str)); } } } |
运行结果:3::黑马_3
2::黑马_2
1::黑马_1
package com.itheima.file; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.Properties; public class PropertiesDemo2 { public static void main(String[] args)throws Exception { //创建一个输入缓冲流 BufferedReader bufr=new BufferedReader(new FileReader(new File("d:"+File.separator+"a.properties"))); //把读取出来的内容存到Properties中 Properties prop=new Properties(); //将流中的数据加载到集合 prop.load(bufr); //打印 System.out.println(prop); } } |
如果我想修改当中的内容怎么办?
package com.itheima.file; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.PrintWriter; import java.util.Properties; public class PropertiesDemo2 { public static void main(String[] args)throws Exception { //创建一个输入缓冲流 BufferedReader bufr=new BufferedReader(new FileReader(new File("d:"+File.separator+"a.properties"))); //把读取出来的内容存到Properties中 Properties prop=new Properties(); //将流中的数据加载到集合 prop.load(bufr); //创建一个输出流 PrintWriter pw= new PrintWriter(new File("d:"+File.separator+"a.properties")); //修改当中的指定键的值 prop.setProperty("time","33"); //存储到指定的文件中区 prop.store(pw, "aaa"); pw.close(); bufr.close(); } } |
从上面的例子中可以看出,setProperty方法只是修改了内存中的值,而硬盘中的值并没有改变,所以Properties集合中海油一种方法,store,这种方法存到流中,进而存到硬盘中去,而list方法之存到流中,要想存到硬盘中,需要调用刷新flush方法。
实例应用:用于记录应用程序运行的次数,如果使用次数已到,给出提示信息
package com.itheima.file; import java.io.File; import java.io.FileInputStream; import java.io.PrintWriter; import java.util.Properties; public class FileDemo3 { public static void main(String[] args)throws Exception { //创建一个Property集合 Properties prop=new Properties(); //创建一个文件对象 File file=new File("d:"+File.separator+"a.properties"); //判断此文件是否存在,不存在则直接创建 if(!file.exists()){ file.createNewFile(); } //创建一个输入流 FileInputStream fis=new FileInputStream(file); //把此流加载到Properties集合中 prop.load(fis); //定义一个计数器 int count=0; //获取一个指定键的值 String value=prop.getProperty("time"); if(value!=null){ //判断是否为null,不为空,就转换成int count=Integer.parseInt(value); if(count>5){ System.out.println("你已经使用了五次,不能再免费使用了"); return; } } count++; prop.setProperty("time", count+""); //然后再把数据写到文件中区 PrintWriter pw=new PrintWriter(file); prop.list(pw); pw.flush(); } } |
2、打印流
(1)PrintWriter
构造函数可以接收的参数
(1)file对象:File (2)字符串路径:String (3)字节输出流:OutputStream (4)字符输出流:Writer |
(2)PrintStream
构造函数可以接收的参数
(1)file对象:File (2)字符串路径:String (3)字节输出流:OutputStream |
例:从键盘录入到文件中
package com.itheima.file; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.io.PrintWriter; public class PrintWriterDemo1 { public static void main(String[] args)throws Exception { //创建一个字符缓冲流 BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in)); //创建一个打印流 PrintWriter pw=new PrintWriter("d:"+File.separator+"a.txt"); //定义一个字符串 String line=null; while((line=bufr.readLine())!=null){ //如果输入over,就结束 if("over".equalsIgnoreCase(line)){ break; } //把从键盘中读取的数据写到指定文件中去 pw.println(line); //刷新 pw.flush(); } //关闭流 pw.close(); bufr.close(); } } |
上面的程序需要刷新才能写到文件中,而PrintWriter定义了一种构造函数,可以直接刷新
PrintWriter pw=new PrintWriter(file,true); |
3、对象序列化
所谓的对象序列化就是将一个在内存中保存的对象变成一个二进制的数据流进行传输。但是并不是所有类的对象都可以进行序列化操作,如果一个对象需要被序列化,则对象所在的类必须实现Serializable接口,但是此接口没有任何的方法定义,所以此接口和Cloneable接口是完全一样的,都是作为标识接口出现。
例:序列化Person对象
package com.itheima.io; import java.io.Serializable; //要实现Seriallizable public class Person implements Serializable{ private String name;//定义name属性 private int age;//定义age属性 //getter和setter方法 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 Person(){} //有参构造函数 public Person(String name,int age){ this.name=name; this.age=age; } //复写toString方法 public String toString(){ return name+","+age; } } |
3.1、序列化对象
ObjectOutputStream主要是序列化对象的使用,也是一个Outputstream的子类
Public ObjectOutputStream(OutputStream out):构造函数 Public final void writeObject(Object obj):输出对象 |
例:
package com.itheima.io; import java.io.File; import java.io.FileOutputStream; import java.io.ObjectOutputStream; public class ObjectOutputStreamDemo1 { public static void main(String[] args)throws Exception { //创建一个Person对象 Person p=new Person("黑马_1",23); //创建一个输出流对象 ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("d:"+File.separator+"heima.ini"))); //序列化对象 oos.writeObject(p); //关闭流 oos.close(); } } |
3.2、反序列化对象
ObjectInputStream就可以完成对象的反序列化
Public ObjectInputStream(InputStream in):构造函数 Public final Object readObject():读取对象 |
例:
package com.itheima.io; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class ObjectInputStreamDemo1 { public static void main(String[] args)throws Exception { //创建一个Person对象 Person p=new Person("黑马_1",23); //创建一个输入流对象 ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("d:"+File.separator+"heima.ini"))); //反序列化对象 Object obj=ois.readObject(); //关闭流 ois.close(); //判断是否是Person if(obj instanceof Person){ //转换成Person对象 Person p1=(Person) obj; System.out.println(p1); } } } |
在进行对象序列化的时候,序列化的是类中的属性,因为每个类的对象只有属性是不同的,
但是如果现有某个属性不希望被序列化,则可以用关键字transient。
Private transient String name; Private int age; |
在正常的情况下ObjectOutputstream只能输出一个对象,如果现在又多个对象要同时进行序列化,则可以使用对象数组的形式完成。对象数组可以直接用Object接受