黑马程序员--IO流(Properties、打印流 、文件切割与合并)

——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();
    }
}

好了,先到这儿

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>