——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
Properties简介:
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。
因为 Properties 继承于 Hashtable,所以可对 Properties 对象应用 put 和 putAll 方法。但不建议使用这两个方法,因为它们允许调用者插入其键或值不是 String 的项。相反,应该使用 setProperty 方法。如果在“不安全”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。类似地,如果在“不安全”的 Properties 对象(即包含非 String 的键)上调用 propertyNames 或 list 方法,则该调用将失败。
此类是线程安全的:多个线程可以共享单个 Properties 对象而无需进行外部同步
Properties是hashtable的子类,也就是说它具备map集合的特点,而且它里面存储的键值对都是字符串,是集合和IO技术相结合的集合容器
用法:按照例子来说
package second;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
/**
* Properties是hashtable的子类,也就是说它具备map集合的特点
* 而且它里面存储的键值对都是字符串,是集合和IO技术相结合的集合容器
* 该对象的特点:
* 可以用于键值对形式的配置文件
* 在加载数据时需要有固定形式:键=值
*
*/
public class PropertiesDemo {
public static void main(String []args){
setAndGet(); //Properties的基本用法
mothed_1();//这个方法太麻烦,我们可以选择用系统提供的load方法,如mothed_2()
mothed_2();
}
//将流中的数据存储到集合中
//将E:\info.txt中的数据放到聚合中
/*
* 1.用流和info.txt文件
* 2.读取一行数据,将该行数据用“=”切割
* 3.用键值对将数据存储到Properties中
*/
public static void mothed_1(){
BufferedReader br=null;
Properties prop=new Properties();
try {
br=new BufferedReader(new FileReader("E:\\info.txt"));
String line=null;
while((line=br.readLine())!=null){
String []arr=line.split("=");
prop.setProperty(arr[0], arr[1]);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(br!=null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println(prop);
}
public static void mothed_2(){
BufferedReader br=null;
BufferedWriter bw=null;
Properties prop=new Properties();
try {
br=new BufferedReader(new FileReader("E:\\info.txt"));
bw=new BufferedWriter(new FileWriter("E:\\info.txt",true));
prop.load(br);//注意这儿,这儿被封装好了
//这儿可以做一些修改的方法
prop.setProperty("wangwu", "39");
prop.store(bw, "modify wangwu to 39");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(br!=null)
br.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
if(bw!=null)
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println(prop);
prop.list(System.out);//Properties的自己的打印方法
}
public static void setAndGet(){
//初始化一个Properties对象
Properties prop=new Properties();
//以键值对的方式存储数据
prop.setProperty("zhangsan", "20");
prop.setProperty("lisi", "30");
//通过键值获取value
String value=prop.getProperty("zhangsan");
System.out.println(value);
//当然我们也可以一次性获取所有的
Set<String>names=prop.stringPropertyNames();
for(String name:names){
System.out.println(name+":"+prop.getProperty(name));
}
}
}
下面做一个练习用于记录程序运行次数,在实际应用中很常见,
比如:有一款试用软件,规定了试用的次数,当试用次数一到,就要提示用户该用正式版了(该花钱了)
package second;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
/**
* 该程序用于记录程序运行次数
* 当我们如果用普通的计数器是,普通计数器是在内存中的,不能持久保存,起不到效果
* 我们的目标是程序结束,该计数器仍然存在,且下次启动程序时,首先加载该计数器,并将其值加1重新存储起来
* 所以我们要建立一个配置文件,用于该软件的使用次数
* 该配置文件使用键值对的形式存储数据,这样便于阅读数据和操作数据
* 键值对数据时map集合,数据是以文件形式存储,使用IO技术
* map + IO ==Properties
* 配置文件可以实现应用程序的数据共享
*
*/
public class RunCount {
public static void main(String []args){
Properties prop=new Properties();
BufferedReader br=null;
BufferedWriter bw=null;
File file=new File("E:\\count.ini");
try {
if(!file.exists())
file.createNewFile();
br=new BufferedReader(new FileReader(file));
bw=new BufferedWriter(new FileWriter(file,true));
prop.load(br);
int count=0;
String value=prop.getProperty("time");
if(value!=null){
count=Integer.parseInt(value);
if(count>=5){
System.out.println("您好,您的试用次数已到,请拿钱!");//呵呵
return;
}
}
count++;
prop.setProperty("time", count+"");
prop.store(bw, "");
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
注:Properties可以放置一些简单的配置信息,如果配置信息非常复杂,逻辑关系很多,建议试用.xml来存储信息
打印流 (PrintStream和PrintWriter)
该流提供了打印方法,可以将各种数据类型的数据原样打印
字节打印流PrintStream
构造函数可以接受的类型:
1.file对象
2.字符串
3.字节输出流
字符打印流PrintWriter
构造函数可以接受的类型:
1.file对象
2.字符串
3.字节输出流
4.字符输出流
相对于字节输出流,字符输出流更常用
下面,我们用字符输出流举例
package third;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class PrintWriterDemo {
public static void main(String[] args){
BufferedReader br =null;
PrintWriter pw =null;
String line=null;
br=new BufferedReader(new InputStreamReader(System.in));//定义一个缓冲流,获取键盘输入
try {
pw=new PrintWriter(System.out,true);//打印到控制台,true是表示自动刷新
// pw=new PrintWriter(new BufferedWriter(new FileWriter("E:\\a.txt")),true);//打印到文件
while((line=br.readLine())!=null){
if("over".equals(line))
break;
pw.println(line.toUpperCase());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
pw.close();
}
}
}
}
注:除了这些外,打印流还可以加入字符集
合并流(SequenceInputStream)
它表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
下面我们做个例子,把三个文件合并为一个,这就需要SequenceInputStream(Enumeration
package third;
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 SequenceDemo {
public static void main(String[] args) {
SequenceInputStream sis=null;
FileOutputStream fos=null;
Vector<FileInputStream>v=new Vector<FileInputStream>();
try {
v.add(new FileInputStream("E:\\1.txt"));
v.add(new FileInputStream("E:\\2.txt"));
v.add(new FileInputStream("E:\\3.txt"));
Enumeration<FileInputStream>e=v.elements();
sis=new SequenceInputStream(e);
fos=new FileOutputStream("E:\\4.txt");
byte[]b=new byte[1024];
int len=0;
while((len=sis.read(b))!=-1){
fos.write(b,0,len);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
sis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
文件切割与合并
把一个大文件切割成若干个小文件,请看实例
package third;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.SequenceInputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
public class SplitAndMergeFile {
public static void main(String[] args) {
try {
split();
merge();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void merge() throws IOException {
ArrayList<FileInputStream> aList = new ArrayList<FileInputStream>();
String dir = "E:\\split\\";
File file = new File(dir);
String[] names = file.list();//这一步可以获取要合并文件的个数,名称与路径
for (String name : names) {
aList.add(new FileInputStream(file + "\\" + name));
}
Iterator it = aList.iterator();
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>() {
@Override
public boolean hasMoreElements() {
return it.hasNext();
}
@Override
public FileInputStream nextElement() {
return (FileInputStream) it.next();
}
};
SequenceInputStream sis = new SequenceInputStream(en);
FileOutputStream fos = new FileOutputStream("E:\\split\\0.avi");
byte[] b = new byte[1024];
int len = 0;
while ((len = sis.read(b)) != -1) {
fos.write(b, 0, len);
}
fos.close();
sis.close();
}
public static void split() throws IOException {
FileInputStream fis = new FileInputStream("E:\\cd.rmvb");// 切割这个视频文件
FileOutputStream fos = null;
byte[] b = new byte[1024 * 1024];
int len = 0;
int time = 0;
int name = 1;
// 每次切割1M,20次为一个文件,
while ((len = fis.read(b)) != -1) {
if (time == 0)
fos = new FileOutputStream("E:\\split\\" + (name++) + ".part", true);
fos.write(b, 0, len);
fos.flush();
time++;
if (time == 20) {
time = 0;
fos.close();
}
}
fis.close();
}
}
好了,先到这儿