Properties概述:
Properties 是hashtable的子类,具备map集合的特点
里面存储的键值对都是字符串,是集合中和IO相结合的集合容器
该类对象的特点:可以用键值对形式的配置文件
在加载数据时要有固定格式,通常是:键=值
1,常用方法列表
steProperty();、getProperty();、设置和获取元素
stringPropertyNames(); JDK1.6 返回属性列表中键集,Map>>Set
load(InputStream inStream) ;JDK1.6 从输入流中读取属性列表(键和元素对)
list(PrintStream out) 将属性列表输出到指定的输出流
stor(OutputStream out, String comments);将此 Properties 表中的属性列表(键和元素对)写入输出流
2,需求:将info.txt中键值数据存储到集合中操作,将流中的数据存到集合中
步骤:
1,将流和info.txt文件关联
2,读取一行数据,将该行数据用"="切割
3,等号左边为键,右边为值,存入Properties集合
操作演示:
import java.io.*;
import java.util.*;
class PropertiesDemo
{
public static void main(String[] args) throws IOException
{
// setAndGet();
// method_1();
loadDemo();
}
public static void loadDemo() throws IOException//三,load,将流加载进集合,操作,存储
{
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("info.txt"); //字节输入流
prop.load(fis); //将流中数据加载进集合
prop.setProperty("xiaoqiang","99");//改变的只是内存中的数据,所以打印出99,但文件中还是22
FileOutputStream fos = new FileOutputStream("info.txt");//字节输出流
prop.store(fos,"haha"); //将prop表中键值对写入到fos输出流
prop.list(System.out);//属性列表,输出到控制台
fos.close();
fis.close();
}
public static void method_1() throws IOException//二,将流中的数据存到集合中
{
BufferedReader bufr = new BufferedReader(new FileReader("info.txt"));//1,文件关联,读取字符流
String line = null;
Properties prop = new Properties();
while ((line=bufr.readLine()) !=null)
{
String[] arr = line.split("="); //2,将每一行劈切割成数组(两个元素)
prop.setProperty(arr[0],arr[1]);//3,等号左键右值,存入集合
}
bufr.close();
sop(prop); //打印集合
}
public static void setAndGet() //一,设置和获取元素
{
Properties prop = new Properties();//隶属于Map集合HashTable
prop.setProperty("xiaoqiang","22");//setProperty在底层调用了Map的put方法
prop.setProperty("zhangsan","33");
// sop(prop);//打印出键值对
String value = prop.getProperty("xiaoqiang");//获取键对应的值,类似于Map中的get()
// sop(value);//打印出22
Set<String> names = prop.stringPropertyNames();//返回属性列表中键集,Map>Set
for(String s : names){
sop(s+" : "+prop.getProperty(s));
}
}
public static void sop(Object obj){
System.out.println(obj);
}
}
运行结果:
Properties应用
需求:记录应用程序运行次数,如果次数已到,给出注册提示
解决思路:很容易联想到计数器,但是计数器定义在程序中,随着程序的运行在内存中存在,并进行自增;可是随着该应用程序的退出,计数器也在内存中消失了,下次启动该程序时,又重新从0开始计数
使程序即使结束,计数器的值也存在,下次程序启动会先加载该计数器并+1后重新存储起来
所以建立一个配置文件,记录该软件运行次数;该配置文件使用键值对的形式,便于阅读和操作
键值对数据时map集合,数据以文件形式存储,使用io技术
即:map+io-->Properties.
实现过程:
import java.io.*;
import java.util.*;
class RunCount
{
public static void main(String[] args) throws IOException
{
Properties prop = new Properties();
File file = new File("count.ini"); //创建文件对象
if (!file.exists())
file.createNewFile();//如果文件不存在,新建一个
FileInputStream fis = new FileInputStream(file);//定义输入流,源
prop.load(fis);//将流中数据加载进集合
String value = prop.getProperty("time");//获取time键的值
int count = 0;//此步骤为了处理value=null的情况,第一次运行将time的value设置为1
if(value !=null){
count = Integer.parseInt(value);//value有值,将字符串解析为十进制数,
if(count>=5){ //限制使用次数
System.out.println("试用次数已到,请注册后使用!");
return;
}
}
count++;
prop.setProperty("time",count+"");//设置time键的值
FileOutputStream fos = new FileOutputStream(file);//定义输出流,目的
prop.store(fos,"haha");
fis.close();//关闭资源
fos.close();
}
}
运行结果
扩展:其它获取数据较为便捷的方式
dom4j开发包 获取数据的,作为了解
打印流
PrintWriter与PrintStream
可以直接操作输入流和文件。(重点)
该流提供了打印方法,可以将各种数据类型的数据原样打印。
PrintWriter
有多个构造函数,可以接受的参数类型:
1,File对象 File
2,字符串路径,String
3,字节输出流,OutputStream
4,字符输出流,Writer
import java.io.*;
class PrintDemo
{
public static void main(String[] args) throws IOException
{
BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));//键盘录入
PrintWriter out = new PrintWriter(new FileWriter("a.txt"),true);//打印流,该方法可自动刷新
String line = null;
while ((line=bufr.readLine()) !=null)
{
if("over".equals(line))
break;
out.println(line.toUpperCase());//打印流可以直接换行打印
// out.flush(); //刷新
}
out.close();
bufr.close();
}
}
序列流
SequenceInputStream
对多个流进行合并。
SequenceInputStream(Enumeration<? extends InputStream> e)
通过记住参数来初始化新创建的 SequenceInputStream,
该参数必须是生成运行时类型为 InputStream及其子类 对象的 Enumeration接口类 型参数。Vector类的方法element()返回值为枚举类型,但是效率不高
示例:将多个文件(输入流)合并为一个(输入流)输出到一个文件上
Vector实现文件合并
import java.io.*;
import java.util.*;
class SequenceDemo
{
public static void main(String[] args) throws IOException
{
Vector<FileInputStream> v = new Vector<FileInputStream>();//Enumeration枚举
v.add(new FileInputStream("g:\\1.txt"));
v.add(new FileInputStream("g:\\2.txt"));
v.add(new FileInputStream("g:\\3.txt"));
Enumeration<FileInputStream> en = v.elements();//返回此向量组件的枚举
SequenceInputStream sis = new SequenceInputStream(en);//应对多个序列流的参数列表使用枚举
FileOutputStream fos = new FileOutputStream("g:\\0.txt");//目的
byte[] buf = new byte[1024];
int len = 0;
while ((len=sis.read(buf)) !=-1)//字节输入流的方法read,返回字符串有效长度
{
fos.write(buf,0,len); //输出
}
fos.close();
sis.close();//序列流是由多个输入流合并成的一个输入流
}
}
文件的分割与合并
主要知识点:序列流,字节流,字节流缓冲区,list集合,迭代器,枚举
由于Vector不够高效,在JDK1.2版本以后被ArrayList替代,枚举对应的迭代器,结构类似,都是取出对象的方法。
而序列流的参数只能是枚举类型,ArrayList又没有实现Enumeration接口,没有返回枚举类型的方法。但是有迭代器,就用匿名内部类的形式,将迭代器获取的ArrayList对象包装成枚举类型,传入序列流。
实现代码:
import java.io.*;
import java.util.*;
class SplitFile
{
public static void main(String[] args) throws IOException
{
splitFile();
merge();
}
public static void merge() throws IOException //2,合并
{
ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
for (int x=1; x<=6 ;x++ ){
al.add(new FileInputStream("g:\\1\\" +x+".part"));
}
final Iterator<FileInputStream> it = al.iterator();//内部类的局部变量要用final修饰
Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
{ //匿名内部类,通过迭代获取对象,转成枚举类型,传递给Sequence
public boolean hasMoreElements(){ //实现枚举接口方法
return it.hasNext();
}
public FileInputStream nextElement(){ //实现方法
return it.next();
}
};//注意分号,匿名内部类
SequenceInputStream sis = new SequenceInputStream(en);//必须传入枚举类型
FileOutputStream fos = new FileOutputStream("g:\\1\\0.mp3");
byte[] buf = new byte[1024*1024];
int len = 0;
while ((len=sis.read(buf)) !=-1){
fos.write(buf,0,len);
}
fos.close();
sis.close();
}
public static void splitFile() throws IOException //1,切割
{
FileInputStream fis = new FileInputStream("g:\\酒红色的心-玉置浩二.mp3");//关联要切割的文件
FileOutputStream fos = null;
byte[] buf = new byte[1024*1024];
int len = 0;
int count = 1;
while ((len=fis.read(buf)) !=-1)//持续读取
{
fos = new FileOutputStream("G:\\1\\"+(count++)+".part");//定义要输出的碎片
fos.write(buf,0,len); //写入字节数据
fos.close(); //每切割一次就关闭一次,因为每次循环都开启了一个新的流
}
fis.close();
}
}