一.Properties集合
1.1体系结构:Map------HashTable----------Properties
1.2 Properties集合特点:
Properties作用:这个集合是用来操作键值对信息配置文件。
1.这个集合是个持久的属性集
2.这个集合可以和IO流关联
3.这个集合中都是字符串,所以不需要泛型
1.3 集合的基本操作
1.创建一个集合:Properties pro=new Properties();//不需要泛型
2.存入元素:pro.setProperty("key","value");
3.修改元素:pro.setProperty("key","value");
4.取出元素有两种方式
a) 通过key值取出:String value=pro.getProperty("key");
b) 通过stringPropertyNames()方法和遍历器取出
Set<String> set=pro.stringPropertyNames();//得到所有的key的set集合
Iterator<.String> it=set.iterator();
While(it.hasNext()){
String key=it.next();
String value=pro.getProperty(key);
System.out.println(key+"="+value);
}
5.将IO流与Properties集合结合操作:
a) 读取配置文件需要一个流对象
BufferedReader bufr=new BufferedReader(new FileReader("info.txt"));
pro.load(bufr);
b) 将操作后的集合存入到配置文件
BufferedWriter bufw=new BufferedWriter(new FileWriter("info.txt"));
Pro.store(bufw,"comment");
6.load()方法原理
String s=null;
while((s=bufr.readLine())!=null){
String[] str=s.split("=");
pro.setProperty(str[0], str[1]);
}
通过配置文件记录运行次数,超过5次就停止
public class PropertiesTest {
/**
* @param args
* @throws IOException
*/
/*
* 需求:定义一个功能记录住程序运行次数。如果次数超过5次,给出提示,试用次数已到请注册。
* 记录次数我们可以通过count计数器,但是计数器在程序关闭后会自动消失,所以需要将计算器持久化
* 我们就联想到使用Properties集合将count持久化,首先将count和1存入进去
*/
public static void main(String[] args) throws IOException {
boolean b=check();
if (b) {
System.out.println("程序运行");
}else {
System.out.println("运行次数已到,给钱");
}
}
public static boolean check() throws IOException {
Properties pro=new Properties();
//首先需要一个文本文件记录配置信息
File config=new File("config.properties");
if(!config.exists()){
config.createNewFile();
}
//需要一个读取流关联文本文件
FileReader fr=new FileReader(config);
pro.load(fr);
String value=pro.getProperty("count");
int num=0;
if(value!=null){
num=Integer.parseInt(value);
if(num>=5){
return false;
}
}
num++;
//将集合中的元素存入文本文件中
FileWriter fw=new FileWriter("config.properties");
pro.setProperty("count",Integer.toString(num));
pro.store(fw, "");
fr.close();
fw.close();
return true;
}
}
二.PrintStream 打印流
PrintStream能够方便的打印各种数据值的表现形式,这个流永远不会抛异常。
//创建一个打印流
PrintStream ps=new PrintStream("print.txt");
//ps.write(97);//609,10-0110-000197,0110-0001//得到最后一个字节的也就是最后8位进行存储,所以97和609都是存a.
ps.print(97);//print方法就是将数据原来的表现形式打印在文本文件中
//print方法原理
String s="609";
byte[] arr=s.getBytes();
//也就是分别存储6、0、 9,6在默认GBK对应的是54 0是48,9是57.
//然后就是write(54) write(48) write(57)写进文件再被解析成609
ps.close();
PrintWriter字符打印
BufferedReaderbufr=newBufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(System.out);
String line=null;
while((line=bufr.readLine())!=null){
if("over".equals(line)){
break;
}
pw.println(line.toUpperCase());
pw.flush();//必须刷新,不然数据都会在缓冲区中,只有关闭才会显示大写的
}
pw.close();
bufr.close();
//想要将数据打印到一个文件中,并刷新。
PrintWriter pw2 = new PrintWriter(new FileWriter("a.txt"),true);
//想要将数据按照指定的编码打印到一个文件中,并刷新。
//PrintWriter pw1 = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a.txt"),"utf-8")),true);
}
三:SequenceInputStream:序列输入流
public class SequenceInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建一个Vector集合对象,目的是为了 获得枚举、
//Vector<FileInputStream> v=new Vector<FileInputStream>();
//但是Vector不管从增删或者查找效率来看都比较低,所以用ArrayList
ArrayList<FileInputStream> v=new ArrayList<FileInputStream>();
v.add(new FileInputStream("1.txt"));
v.add(new FileInputStream("2.txt"));
v.add(new FileInputStream("3.txt"));
//枚举相当于迭代器,只是枚举没人用。
//Enumeration<FileInputStream> en=v.elements();
/*
* 我们可以通过自己新建一个枚举对象
* 新建一个匿名内部类,它内部实现方法和迭代器一样的,所以可以通过迭代器的hasNext next实现功能
* 而匿名内部类只能访问局部被final修饰的变量,所以it需要final。
*/
/*
final Iterator<FileInputStream> it=v.iterator();
Enumeration<FileInputStream> en=new Enumeration<FileInputStream>(){
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public FileInputStream nextElement() {
return it.next();
}
};*/
//查帮助文档我们可以发现Collections工具类有一个获得枚举对象的方法
//这个方法原理还是通过上面的匿名内部类的功能实现。
Enumeration<FileInputStream> en=Collections.enumeration(v);
//创建对象流,将多个源变成一个源
SequenceInputStream sis=new SequenceInputStream(en);//接收一个枚举对象
FileOutputStream fos=new FileOutputStream("4.txt");
byte[] but=new byte[1024];
int c=0;
while((c=sis.read(but))!=-1){
fos.write(but, 0, c);
}
fos.close();
sis.close();
}
}
四:对象的序列化及反序列化
public class ObjectStreamDemo {
/*
* 对象操作流:ObjectInputStream ObjectOutputStream
* ObjectOutputStream:ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream
* 对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。
* ObjectInputStream:对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
*serialVersionUID:类的签名,序列化在运行时会有个serialVersionUID的版本号
*与每个可序列化类相关联。可以保证类修改后还是可以读取原来的。通过UID号。
*Person类必须实现这Serializable接口:用于给类定义serialVersionUID号用的。这个接口就是一个标识(规则)。里面没有方法
*静态数据不能序列化,因为存储空间不一样,
*tranSient:瞬态,类的属性被她修饰,生命周期变短,不能序列化。
*/
Public static void main(String[] args) throws IOException, ClassNotFoundException {
//writerMethod();
readerMethod();
}
//对象反序列化
public static void readerMethod() throws IOException, IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("10.txt"));
Person p=(Person)ois.readObject();
System.out.println(p.getAge()+p.getName());
}
//对象序列化
public static void writerMethod() throws IOException, IOException {
//创建Person对象
Person p=new Person("asq",22);
//创建对象输出流
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("10.txt"));
//将对象序列化
oos.writeObject(p);
oos.close();
}
}