IO流总结

本文深入探讨Java IO流操作,包括字节流与字符流的使用,键盘录入数据存储,文件复制与过滤,以及利用SequenceInputStream合并多个文件。同时,介绍了如何使用Properties类进行配置信息的读写。

1、IO流总结

字节流

FileInputStream

FileOutputStream

BufferedInputStream

BufferedOutputStream

字符流

FileReader

FileWriter

InputStreamReader  //转换流

OutputStreamWriter  //转换流

BufferedReader

BufferedWriter

所学习的对象,都是用于操作文件中数据的对象,有可以进行字符编码转换的,有可以提供效率的。

2、键盘录入

需求:将键盘录入的数据存储到文件中。

package readKey;

import java.io.IOException;
import java.io.InputStream;

public class ReadKeyDemo {
    public static void main(String[] args) throws IOException {
        /*
        需求:将键盘录入的数据存储到文件中
        键盘录入是输入。键盘录入都是字节
        在System类中找到了标准输入流,属性in,对应的类型是InputStream,字节输入流,这个流可以不用关闭
         */
        InputStream in = System.in; //获取了键盘录入的输入流对象

//        System.out.println((int)'\r'); //13
//        System.out.println((int)'\n'); //10
//
//        int ch = in.read();
//        System.out.println(ch);
//        int ch1 = in.read();
//        System.out.println(ch1);
//        int ch2 = in.read();
//        System.out.println(ch2);
//        int ch3 = in.read();
//        System.out.println(ch3);
        

    }
}

上述例子,如果只输入一个a,那么输出的为97、13、10,原因是读取到了回车行。

怎么一次读取一片数据呢?

package readKey;

import java.io.*;
import java.nio.Buffer;

public class demo2 {
    //读取的数据更多
    public static void main(String[] args) throws IOException {
        /*
        读取一个字节,先不要操作,先存储,然后转成一个字符串。
        能不能一次读取一行字符串呢? readLine();
        可是readLine是BufferedReader方法。其使用时必须接收字符流对象,键盘录入是字节流,怎么转换?
        字节流---桥梁(InputStreamReader)---字符流
         */
        //字节流
        //通过桥梁将字节输入流转称字符输入流
        //对字符流进行效率的提高,使用readline

        //以后但凡提到了键盘录入,就写这一句,一行一行的读取,除非要对读取的每一个字节操作
        BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while ((line = bfr.readLine())!=null){ //键盘录入没办法终止,要记住定义结束标记
            System.out.println(line);
            if("end".equals(line)){
                break;
            }
        }
        //真正操作的是system.in,上述不过提供了转换功能和高效功能,所以可以不关流
    }
}

3、将键盘录入的数据存储到文件中

package readKey;

import java.io.*;

public class save {
    public static void main(String[] args) throws IOException {
        //键盘录入的数据存储到文件中
        //1、键盘录入
        //2、目的是文件
        //3、这个示例中,既要用到输入流,也要用到输出流
        //4、操作的数据是文本数据,可以使用字符流
        //5、目的是文件,可以使用操作文件的字符输出流
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //目的是文件
        FileWriter fw = new FileWriter("F:\\javatest\\keytest.txt");
        BufferedWriter bw = new BufferedWriter(fw);

        String line = null;
        while ((line = br.readLine())!= null){
            bw.write(line);
            bw.newLine();
            bw.flush();
            if (line.equals("end")){
                System.out.println("over");
                break;
            }
        }
        bw.close();
    }
}

4、IO流的对象使用规律总结

IO流中,对象很多,解决问题时(处理设备上位置),到底该用哪个对象呢?

把IO流进行规律的总结


明确一:

要操作的数据是数据源还是数据目的。

源:InputStream、Reader

目的:outputStream、Writer

先根据需求明确了要读还是要写。


明确二:要操作的设备上的数据是字节还是文本。

源:

如果源是字节,用InputStream

如果源是文本,用Reader

目的:

如果目的是字节,用OutputStream

如果目的是文本,用Writer

已经明确到了具体的体系上。


明确三:明确数据所在的具体设备

源设备:

硬盘(文件  File开头)、内存(数组,字符串)、键盘(System.in)、网络(Socket)

目的设备(数据汇):

硬盘(文件  File开头)、内存(数组,字符串)、屏幕(System.out)、网络(Socket)


完全可以明确具体要使用哪个流对象。

明确四:是否需要额外功能

额外功能:

需要转换吗?转化流。桥梁、编码转换。InputStreamReader   OutPutStreamWriter

需要高效吗?缓冲区对象 BufferedXXX

有多个源吗(字节流)? 序列流 SequenceInputStream

对象需要序列化吗? ObjectInputStream ObjectOutputStream

需要保证数据输出的表现形式吗? 打印流 PrintStream PrintWriter

需要操作基本类型数据保证字节原样性吗? DataOutputStream  DataInputStream


练习:

需求0:将字符串写入到文件中。

明确一:

源:字符串,String (不用IO,直接定义String字符串就可以了)

目的:文件 (使用IO,输出流 OutputStream、Writer)

明确二:

是文本数据,目的中用Writer。

明确三:

具体设备是硬盘,File开头的对象,Writer体系中的。明确具体对象FileWriter

FileWriter fw = new FileWriter("a.txt");

fw.writer(String);

明确四:

需要额外功能,需要高效

BufferedWriter bfw = new BufferedWriter(new FileWriter("a.txt"));

bfw.writer(String);

bfw.newLine();

bfw.flush();

bfw.close();

---------------------------------------------------------------------------------------------------

需求1:复制一个文本文件,有可能对复制过程中的文本进行过滤。

明确一:

有源(InputStream、Reader)、有目的(OutputStream、Writer)

明确二:

是纯文本文件,使用Reader和Writer

强调一点,如果仅做复制动作,不需要考虑数据是字节还是文本。直接使用字节流。

但是,如果在复制过程中,需要对文本中的字符数据进行操作,就必须使用字符流。

明确三:

具体的源设备为硬盘(File开头)、目的设备为硬盘(File开头)

明确四:

额外功能,缓冲区。

BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bfw = new BufferedWriter(new FileWriter("a.txt"));
String line;
line = bfr.readLine();
line = line.replace("nba","cba");
bufw.writer(line);

-------------------------------------------------------------------------------------------------- 

需求2:读取键盘录入将数据存储到文件中

明确一:

有源(InputStream、Reader),有目的(OutputStream、Writer)

明确二:

源:纯文本(Reader)、目的(Writer)

明确三:

具体的设备

源:键盘(System.in)

目的:硬盘(FileWriter)

InputStream in = System.in;
FileWriter fw = new FileWriter("a.txt");
byte[] buf = new byte[1024];
int len = in.read(buf);
String str = new String(buf,0,len);
fw.writer(str);
//有问题,如果缓冲区最后一个字节是中文的一半,怎么办?很麻烦

明确四:

需要额外功能: 转换,因为明确源的体系是Reader,可是具体设备是System.in,是字节流。需要转换功能,将字节流转换成字符流   InputStreamReader

InputStreamReader isr = new InputStreamReader(System.in);
FileWriter fr = new FileWriter("a.txt");

 还需要额外功能:高效

BufferedReader bufr = new BufferedReader(isr);
BufferedWriter bufw = new BufferedWriter("a.txt");

----------------------------------------------------------------------------------------------------------------- 

需求3:读取文本文件,打印在屏幕上

明确一:有源(InputStream、Reader),有目的(OutputStream、Writer)

明确二:源:Reader、目的:Writer;

明确三:源:硬盘,FileReader、目的:屏幕,System.out

FileReader fr = new FileReader("a.txt");
PrintStream out = System.out;
out.println();
//其实这样就已经完成需求
printStream对象中有N多的print方法
fr.read();
System.out.println();

明确四:额外功能

BufferedReader bfr = new BufferedReader(new FileReader("a.txt"));
BufferedWriter bufw = new BufferedWrtier(new OutputStreamWriter(System.out));

 -----------------------------------------------------------------------------------------------------------

需求4:读取文件中的文本数据,将数据按照UTF-8的方式存储到文件中

明确一:有源(InputStream、Reader) 有目的(OutputStream、Writer)

明确二:是文本,源Reader、目的Writer

明确三:源为硬盘FileReader、目的为硬盘FileReader

FileReader fr = new FileReader("a.txt");
FileWriter fw = new FileWriter("b.txt");

明确四:需要转换、需要高效

FileReader fr = new FileReader("a.txt");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("b.txt"),"UTF-8");
BufferedReader bufr = new BufferedReader("a.txt");
BufferedWriter bufw = new BufferedWriter(new FileOutputStream("b.txt"),"UTF-8");

 -----------------------------------------------------------------------------------------------------------------------

5、练习:将一个媒体文件切割成多个碎片

package readKey;

import java.io.*;

public class splitfileDemo {
    private static final int BUFFER_SIZE = 1048576;

    /*
        练习:将一个媒体文件切割成多个碎片
        1、读取源文件,将源文件的数据分别复制到多个文件中
        2、切割方式有两种:按照碎片个数切,要么按照指定大小切
        3、一个输入流对应多个输出流
        4、每一个碎片都需要编号,顺序不要错
         */
    public static void main(String[] args) throws IOException {
        File srcfile = new File("F:\\javatest\\1.mp3");
        File partDir = new File("F:\\javatest\\partFiles");
        splitfile(srcfile,partDir);
    }
    /*
    用于切割文件
     */
    public static void splitfile(File srcfile, File partDir) throws IOException {
        //健壮性判断
        if(!(srcfile.exists()&&srcfile.isFile())){
            throw new RuntimeException("源文件不存在");
        }
        if(!partDir.exists()){
            partDir.mkdirs();
        }
        //1、使用字节流读取和源文件关联
        FileInputStream fis = new FileInputStream(srcfile);
        //2、明确目的。目的输出流有多个,只创建引用
        FileOutputStream fos = null;
        //3、定义缓冲区
        byte[] buf = new byte[BUFFER_SIZE];
        //4、频繁读写操作
        int len = 0;
        int count = 1;
        while ((len = fis.read(buf))!=-1){
            //创建输出流对象,只要满足了缓冲区大小,碎片数据确定,就直接写数据
            //碎片文件存储到partDir中
            fos = new FileOutputStream(new File(partDir,(count++)+".part"));
            //将缓冲区中数据写入
            fos.write(buf,0,len);
            fos.close();
        }
        fis.close();
    }
}

问题:对方下载下来不知道碎片该合成什么文件。

1、把这些信息写在碎片里面去。

2、把信息写到单独的文件中

package readKey;

import java.io.*;

public class splitfileDemo {
    private static final int BUFFER_SIZE = 1048576;

    /*
        练习:将一个媒体文件切割成多个碎片
        1、读取源文件,将源文件的数据分别复制到多个文件中
        2、切割方式有两种:按照碎片个数切,要么按照指定大小切
        3、一个输入流对应多个输出流
        4、每一个碎片都需要编号,顺序不要错
         */
    public static void main(String[] args) throws IOException {
        File srcfile = new File("F:\\javatest\\1.mp3");
        File partDir = new File("F:\\javatest\\partFiles");
        splitfile(srcfile,partDir);
    }
    /*
    用于切割文件
     */
    public static void splitfile(File srcfile, File partDir) throws IOException {
        //健壮性判断
        if(!(srcfile.exists()&&srcfile.isFile())){
            throw new RuntimeException("源文件不存在");
        }
        if(!partDir.exists()){
            partDir.mkdirs();
        }
        //1、使用字节流读取和源文件关联
        FileInputStream fis = new FileInputStream(srcfile);
        //2、明确目的。目的输出流有多个,只创建引用
        FileOutputStream fos = null;
        //3、定义缓冲区
        byte[] buf = new byte[BUFFER_SIZE];
        //4、频繁读写操作
        int len = 0;
        int count = 1;
        while ((len = fis.read(buf))!=-1){
            //创建输出流对象,只要满足了缓冲区大小,碎片数据确定,就直接写数据
            //碎片文件存储到partDir中
            fos = new FileOutputStream(new File(partDir,(count++)+".part"));
            //将缓冲区中数据写入
            fos.write(buf,0,len);
            fos.close();
        }
            /*
    将源文件以及切割的一些信息也保存起来随着碎片文件一起发送
    1、源文件的名称。类型
    2、切割的碎片的个数。
    单独封装到一个文件中,还需要一个输出流完成此动作
     */
        String filename = srcfile.getName();
        int partcount = count;
        //再创建一个输出流
        fos = new FileOutputStream(new File(partDir,count+".partconfig"));
        fos.write(filename.getBytes());
        String s = "\r\n";
        fos.write(s.getBytes());
        fos.write((Integer.toString(partcount)).getBytes());
        fos.close();
        fis.close();
    }


}

6、如何取读取partconfig

package readKey;

import java.io.*;

public class ReadPartconfig {
    //解析partconfig文件中的信息
    public static void main(String[] args) throws IOException {
        File configFile = new File("F:\\javatest\\partFiles\\6.partconfig");
        readpartconfig(configFile);
    }

    private static void readpartconfig(File configFile) throws IOException {
        //配置文件规律,只要读取一行文本,按照=对文本进行切割即可。
        BufferedReader br = new BufferedReader(new FileReader("F:\\javatest\\partFiles\\6.partconfig"));
        String line = null;
        while ((line = br.readLine())!=null){
            String[] arr = line.split("=");
            System.out.println(arr[0]+":"+arr[1]);
        }
        br.close();
    }
}

信息只要一多,就存起来,使用集合。

HashTable有个子类非常吊,就是properties

通常这个集合就用于配置文件的操作

特点:1、没有泛型 2、键值对都是字符串 3、可保存在流中或从流中进行加载

7、properties

基本方法和功能

package propertiesDemo;

import java.util.Properties;
import java.util.Set;

public class propertiDemo {
    public static void main(String[] args) {
        //Properties集合的使用
        method_1();
    }
    //基本使用
    public static void method_1(){
        Properties pp = new Properties();
        //添加数据
        //pp.put()方法,存进去的是object对象,setproperty()方法存的才是String字符串
        pp.setProperty("leo","24");
        pp.setProperty("zhang","22");
        //获取数据
        String str = pp.getProperty("leo");
        System.out.println(str);
        //全部取出  map--set--iterator
        Set<String> set = pp.stringPropertyNames();
        for(String name:set){
            String value = pp.getProperty(name);
            System.out.println(name+":"+value);
        }
    }
}

和IO结合的方法

  list();将属性列表输出到指定的输出流。调试用的方法,不需要展现。

package propertiesDemo;

import java.util.Properties;
import java.util.Set;

public class propertiDemo {
    public static void main(String[] args) {
        //Properties集合的使用
        method_1();
    }
    //基本使用
    public static void method_1(){
        Properties pp = new Properties();
        //添加数据
        //pp.put()方法,存进去的是object对象,setproperty()方法存的才是String字符串
        pp.setProperty("leo","24");
        pp.setProperty("zhang","22");
        pp.list(System.out);

    }
}

  load(); 从输入流中读取属性列表(键和元素对)

package propertiesDemo;

import java.io.*;
import java.util.Properties;
import java.util.Set;

public class propertiDemo {
    public static void main(String[] args) throws IOException {
        //Properties集合的使用
        //method_1();
        //method_2();  //从流中加载的方法,持久化动作  load();
        method_3(); //保存到流中  store();
    }

    private static void method_3() throws IOException {
        File configtest = new File("F:\\javatest\\configtest.txt");

        Properties pp = new Properties();
        pp.setProperty("leo","23");
        pp.setProperty("zhang","22");
        FileWriter fw = new FileWriter(configtest);
        pp.store(fw,"info");
        fw.close();

    }

    private static void method_2() throws IOException {
        File configFile = new File("F:\\javatest\\partFiles\\6.partconfig");
        FileReader fr = new FileReader(configFile);

        Properties pp  = new Properties();
        //使用properties集合的load方法就可以将流中的数据加载到集合中,原理就是ReadPartconfig类(readkey包中)的方法
        pp.load(fr);
        System.out.println(pp);
        fr.close();
    }

    //基本使用
    public static void method_1(){
        Properties pp = new Properties();
        //添加数据
        //pp.put()方法,存进去的是object对象,setproperty()方法存的才是String字符串
        pp.setProperty("leo","24");
        pp.setProperty("zhang","22");
        pp.list(System.out);

    }
}

8、切割文件-通过properties操作配置信息

package readKey;

import java.io.*;
import java.util.Properties;

public class splitfileDemo {
    private static final int BUFFER_SIZE = 1048576;

    /*
        练习:将一个媒体文件切割成多个碎片
        1、读取源文件,将源文件的数据分别复制到多个文件中
        2、切割方式有两种:按照碎片个数切,要么按照指定大小切
        3、一个输入流对应多个输出流
        4、每一个碎片都需要编号,顺序不要错
         */
    public static void main(String[] args) throws IOException {
        File srcfile = new File("F:\\javatest\\1.mp3");
        File partDir = new File("F:\\javatest\\partFiles");
        splitfile(srcfile,partDir);
    }
    /*
    用于切割文件
     */
    public static void splitfile(File srcfile, File partDir) throws IOException {
        //健壮性判断
        if(!(srcfile.exists()&&srcfile.isFile())){
            throw new RuntimeException("源文件不存在");
        }
        if(!partDir.exists()){
            partDir.mkdirs();
        }
        //1、使用字节流读取和源文件关联
        FileInputStream fis = new FileInputStream(srcfile);
        //2、明确目的。目的输出流有多个,只创建引用
        FileOutputStream fos = null;
        //3、定义缓冲区
        byte[] buf = new byte[BUFFER_SIZE];
        //4、频繁读写操作
        int len = 0;
        int count = 1;
        while ((len = fis.read(buf))!=-1){
            //创建输出流对象,只要满足了缓冲区大小,碎片数据确定,就直接写数据
            //碎片文件存储到partDir中
            fos = new FileOutputStream(new File(partDir,(count++)+".part"));
            //将缓冲区中数据写入
            fos.write(buf,0,len);
            fos.close();
        }
            /*
    将源文件以及切割的一些信息也保存起来随着碎片文件一起发送
    1、源文件的名称。类型
    2、切割的碎片的个数。
    单独封装到一个文件中,还需要一个输出流完成此动作
     */
        String filename = srcfile.getName();
        int partcount = count;
        //再创建一个输出流
        fos = new FileOutputStream(new File(partDir,count+".properties"));
//        fos.write(("filename="+filename).getBytes());
//        String s = "\r\n";
//        fos.write(s.getBytes());
//        fos.write(("partcount="+(Integer.toString(partcount))).getBytes());
        //创建一个属性集
        Properties prop = new Properties();
        //将配置信息存储到属性集中
        prop.setProperty("filename",srcfile.getName());
        prop.setProperty("partcount",Integer.toString(partcount));
        //持久化
        prop.store(fos,"part file info");
        fos.close();
        fis.close();
    }


}

9、IO练习-合并文件-序列流(解决多个源合并成一个源的问题)

当流对象过多,必须先存储起来。面对流对象的容器操作更容易

1、需要容器

2、将流对象和碎片文件关联后存储到容器中

3、遍历容器获取其中的流对象,再进行频繁的读写操作

4、即使关流也是遍历容器对每一个流对象进行close的调用

package readKey;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class mergefile {
    public static void main(String[] args) throws IOException {
        //合并碎片文件
        //思路:
        //1、每一个碎片都需要和读取流关联
        //2、每个读取流读取到的数据都需要通过一个输出流写入到一个文件中
        //3、原理:多个源--》一个目的地
        List<FileInputStream> list = new ArrayList<FileInputStream>();
        for(int i=1;i<7;i++){
            list.add(new FileInputStream("F:\\javatest\\partFiles\\"+i+".part"));
        }
        FileOutputStream fos = new FileOutputStream("F:\\javatest\\partFiles\\2.mp3");
        byte[] buf = new byte[1024*1024];
        //遍历集合,获取流对象
        for(FileInputStream fis:list){
            int len = fis.read(buf);
            fos.write(buf,0,len);
        }
        fos.close();
        //关闭所有流对象
        for(FileInputStream fis:list){
            fis.close();
        }

    }
}

把三个流合并成一个流

class MyMergeStream{
    public MyMergeStream(List<? extends InputStream> list){
        
    }
    public void close() throws IOException {
        for(InputStream fis:list){
            fis.close();
        }
    }
}

找一下有没有这样的对象?

序列流对象:SequenceInputStream

只有读,没有写。

表示其他输入流的逻辑串联。从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。

package readKey;

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

public class mergeFileDemo {
    public static void main(String[] args) throws IOException {
        //使用序列流合并数据
        File partsDir = new File("F:\\javatest\\partFiles");
        merge(partsDir);
    }

    private static void merge(File partsDir) throws IOException{
        //使用io包中的SequenceInputStream 对碎片文件进行合并
        List<FileInputStream> list = new ArrayList<FileInputStream>();
        for (int i = 1;i<6;i++){
            list.add(new FileInputStream("F:\\javatest\\partFiles\\"+i+".part"));
        }
        //怎么获取枚举对象?List自身无法获取枚举对象,可以考虑到集合框架工具类中找,找不到,自己写。
        Enumeration<FileInputStream> en= Collections.enumeration(list);
        //源。
        SequenceInputStream sis = new SequenceInputStream(en);
        //目的
        FileOutputStream fos = new FileOutputStream(new File(partsDir,"3.mp3"));
        //不断的读写
        byte[] buf = new byte[4096];
        int len = 0;
        while ((len = sis.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        fos.close();
        sis.close();
    }
}

小问题

1、你怎么知道碎片叫part

2、你怎么知道循环是6次

3、有没有想到最后一个碎片会没有接收到?

4、文件合并完是mp3吗?

解决方法

package readKey;

import java.io.*;
import java.util.*;

public class mergeFileDemo {
    public static void main(String[] args) throws IOException {
        //使用序列流合并数据
        File partsDir = new File("F:\\javatest\\partFiles");
        File configFile = getConfigFile(partsDir);
        Properties prop = getProperties(configFile);
        //将属性集对象传递到合并方法中
        merge(partsDir,prop);
        //1、获取配置文件信息容器。获取配置信息的属性集。
    }

    //根据配置文件获取配置信息属性集
    private static Properties getProperties(File configFile) throws IOException {
    FileInputStream fis = null;
    Properties prop = new Properties();
    try{ //读取流和配置文件相关联
        fis = new FileInputStream(configFile);
        //将流中的数据加载到集合中
        prop.load(fis);
    }finally {
        if(fis!=null){
            fis.close();
        }
    }
    return prop;
    }


    //根据碎片目录获取配置文件对象
    private static File getConfigFile(File partsDir) {
        if(!(partsDir.exists()&&partsDir.isDirectory())){
            throw new RuntimeException(partsDir.toString()+"不是有效目录");
        }
        //1、判断碎片文件目录中是否存在properties文件,使用过滤器完成
        File[] files = partsDir.listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.getName().endsWith(".properties");
            }
        });
        if(files.length!=1){
            throw new RuntimeException(partsDir.toString()+"properties扩展名的文件不存在,或不唯一");
        }
        File configFile = files[0];
        return configFile;
    }

    private static void merge(File partsDir,Properties prop) throws IOException{
        /*
        虽然合并成功,但是问题如下
        1、如何明确碎片的个数来确定循环的次数,以明确要有多少个输入流对象。
        2、如何知道合并的文件的类型。
        解决方案:应该先读取配置文件。
         */
        String fileName = prop.getProperty("filename");
        int partCount = Integer.parseInt(prop.getProperty("partcount"));

        //使用io包中的SequenceInputStream 对碎片文件进行合并
        List<FileInputStream> list = new ArrayList<FileInputStream>();
        for (int i = 1;i<partCount;i++){
            list.add(new FileInputStream("F:\\javatest\\partFiles\\"+i+".part"));
        }
        //怎么获取枚举对象?List自身无法获取枚举对象,可以考虑到集合框架工具类中找,找不到,自己写。
        Enumeration<FileInputStream> en= Collections.enumeration(list);
        //源。
        SequenceInputStream sis = new SequenceInputStream(en);
        //目的
        FileOutputStream fos = new FileOutputStream(new File(partsDir,fileName));
        //不断的读写
        byte[] buf = new byte[4096];
        int len = 0;
        while ((len = sis.read(buf))!=-1){
            fos.write(buf,0,len);
        }
        fos.close();
        sis.close();
    }
}

10、io流练习-记录程序运行的次数

练习:定义功能记录程序运行次数,满足使用次数后,给出提示:使用次数已到,请注册。

思路:

1、需要计数器

2、计数器是程序中的一个变量,程序启动计数器计数,可是,程序结束,计数器就消失,需要永久化存储。

3、持久化的属性集 properties

package readKey;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class appCountDemo {
    public static void main(String[] args) throws IOException {
        //记录程序运行次数
        if(isStop()){
            System.out.println("play limit!");
            return;
        }
        runcode();
    }

    private static boolean isStop() throws IOException {
        //1、配置文件
        File configFile = new File("F:\\javatest\\app.Properties");
        //如果配置文件不存在,就创建
        if(!(configFile.exists())){
            configFile.createNewFile();
        }
        //2、创建属性集
        Properties prop = new Properties();
        //3、定义读取流
        FileInputStream fis = new FileInputStream(configFile);
        //4、将流关联
        prop.load(fis);
        //5、通过指定的键count,获取具体的次数
        String value = prop.getProperty("count");
        int count = 0;
        //6、对value进行判断,如果存在,就自增
        if (value != null) {
            count = Integer.parseInt(value);
            if (count >= 5) {
                return true;
            }
        }
        count++; //对其值进行自增
        //将自增后的值和指定的键重新存储到属性集中,键相同,值替换
        prop.setProperty("count",Integer.toString(count));
        //7、对配置文件中的信息进行更新
        FileOutputStream fos = new FileOutputStream(configFile);
        prop.store(fos, "appcount");
        fos.close();
        fis.close();

        return false;
    }

    private static void runcode() {
        System.out.println("start!");
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值