你的位置:首页 > Java教程

[Java教程]IO流(五)__文件的递归、Properties、打印流PrintStream与PrintWriter、序列流SequenceInputStream


一、文件的遍历

1.需求:对指定目录进行所有的内容的列出(包含子目录的内容)—文件的深度遍历

思想:递归的思想,在递归的时候要记住递归的层次。

public class FileTest {  public static void main(String[] args) {    File dir =new File("e:\\java\\JavaSE基础视频");    listAll(dir,0);      }  private static void listAll(File dir,int level) {    level++;    //level记录递归的层次    //获取指定目录下当前的所有文件夹或者文件对象    File[] files=dir.listFiles();    for (int i = 0; i < files.length; i++) {      if(files[i].isDirectory()){        listAll(files[i],level); //递归      }      else      System.out.println(getSpace(level)+files[i].getName());    }      }  private static String getSpace(int level) {    StringBuilder sb=new StringBuilder();    sb.append("|--");    for (int i = 0; i < level; i++) {      sb.insert(0,"| ");    }            return sb.toString();  }}

2.需求:删除指定文件夹中的所有内容

思想:必须从里面往外删除,进行深度遍历

public class RemoveDirTest {  public static void main(String[] args) {    File dir=new File("e://111");    removeDir(dir);    }   //这种删除是彻底删除,不经过回收站  private static void removeDir(File dir) {    File [] files=dir.listFiles();    for (File file : files) {      if(file.isDirectory()){        removeDir(file);      }else{        file.delete();      }    }    dir.delete();      }}

 

二、Properties

* properties继承自hashtable
* 特点
* 1.该集合中的键和值都是字符串类型

* 2.集合中的数据可以保存在流中,或者从流获取

* 3.map+io=Properties

* 通常该集合用于操作以键值对形式存在的配置文件
* 配置信息:键值对

  private static void propertiesDemo_5() throws IOException {    //读取这个文件    File file=new File("ifo.txt");     if(!file.exists()){      file.createNewFile();    }    FileReader fr=new FileReader("ifo.txt");        //创建集合存储配置信息    Properties prop =new Properties();        //将流中信息存储在集合中    prop.load(fr);        //添加属性    prop.setProperty("zhaoliu","52");        FileWriter fw =new FileWriter(file);    //持久化    prop.store(fw, "comment");    //在控制台打印    prop.list(System.out); // 方法:public void list(PrintStream out)    fw.close();    fr.close();          }

例一:

 定义功能:获取一个应用程序运行的次数,如果超过五次,如果超过五次给出使用次数已到请注册的提示。并不要运行程序。

思路
* 1.应该有计数器
* 每次程序启动都需要计数一次,并且是在原有的次数上进行计数
* 2.计数器就是一个变量。计数器不许在内存并进行运算
* 而我们需要多次启动同一个应用程序,使用的是同一个计数器
* 这就需要计数器的生命周期变长,从内存存储到硬盘文件中
* 3.首先,程序启动时,应该先访问这个用于记录计数器的信息的配置文件
* 获取上一次计数器次数。并进行使用此时的判断
* 其次,对次数进行自增,并自增后的次数重新存储到配置文件中
* 4.文件中的信息该如何进行存储并体现
* 直接存储次数可以,但是不明确该数据的含义。所以起名字变得很总要
* 这就有了名字和值的对应,所以可以使用键值对
* 可是映射关系map集合搞定,又要读取硬盘上的数据,所有map+io=Properties

public class PropertiesTest {  public static void main(String[] args) throws IOException {        //将配置文件封装成File对象      File config=new File("count.properties");      if(!config.exists()){        config.createNewFile();      }      FileInputStream fis=new FileInputStream(config);      Properties prop=new Properties();      prop.load(fis);            //从集合中通过键获取次数      String value =prop.getProperty("time");      //定义计数器。记录获取到的次数      int count=0;      if(value!=null){        count=Integer.parseInt(value);        if(count>=6){          throw new RuntimeException("使用次数已到,请注册,给钱!");                }      }            count++;      //将改变后的次数重新存储到集合中      prop.setProperty("time", String.valueOf(count));      FileOutputStream fos=new FileOutputStream(config);      prop.store(fos,"count");      fos.close();      fis.close();                      }      }    

View Code

 

例二:

需求:获取指定目录下,指定扩展名的文件(包含子目录中的),这些文件的绝对路径写入到一个文本文件中。

思路
* 1.必须进行深度遍历
* 2.要在遍历的过程中进行过滤。将符合条件的内容都存储到容器中
* 3.对容器中的内容进行遍历并将绝对路径写入到文件中

public class Test {  public static void main(String[] args) throws IOException {    File dir=new File("E:\\JAVA\\JAVA练习");    FilenameFilter filter =new FilenameFilter(){      @Override      public boolean accept(File dir, String name) {                return name.endsWith(".java");      }          };    List<File> list =new ArrayList<File>();    getFiles(dir,filter,list);    File destFile =new File("javalist.txt");    writeToFile(list,destFile);      }  public static void getFiles(File dir,FilenameFilter filter,List<File> list){    File[] files=dir.listFiles();    for (File file : files) {      if(file.isDirectory()){        getFiles(file,filter,list);//递归      }      else      {        //对遍历到的文件进行过滤器的过滤        //将符合条件File对象存储到List集合中                if(filter.accept(dir,file.getName())){          list.add(file);        }        }    }  }    public static void writeToFile(List<File> list,File destFile) throws IOException{    BufferedWriter bufw=new BufferedWriter(new FileWriter(destFile));    for (File file : list) {      bufw.write(file.getAbsolutePath());      bufw.newLine();      bufw.flush();    }  }  }

View Code

 

三、打印流PrintStream和PrintWriter

打印流--必须是输出流(两个都是)

system.out流就是PrintStream的子类

区别

1.PrintStream(字节流) PrintWriter(字符流)

2.使用PrintStream进行输出,可以不用指定手动刷新或者设置自动刷新即可完成输出,而PrintWriter则不同,

一定要在构造方法中设置自动刷新(构造函数中autoFlush置为true)或者在调用println()方法以后再调用flush(),才可以立即完成输出。

public class PrintStreamDemo {  public static void main(String[] args) throws IOException {    BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));    PrintStream out =new PrintStream("print1.txt");    String line=null;    while ((line=bufr.readLine())!=null){      if("over".equals(line))        break;      out.println(line.toUpperCase());      //out.flush();    }        out.close();    bufr.close();  }}

public class PrintWriterDemo {  public static void main(String[] args) throws IOException {    BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));    //PrintWriter out=new PrintWriter(System.out);    PrintWriter out=new PrintWriter(new FileWriter("PrintWriter.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

需求:将三个文件中的数据并到一个文件中

public class SequenceInputStreamDemo {  public static void main(String[] args) throws IOException {/* * 需求:将三个文件中的数据并到一个文件中 */        ArrayList<FileInputStream> al=new ArrayList<FileInputStream>();    for (int i = 1; i <= 3; i++) {      al.add(new FileInputStream(i+".txt"));    }    Enumeration<FileInputStream> en=Collections.enumeration(al);//使用collection的静态方法获取枚举对象    SequenceInputStream sis=new SequenceInputStream(en); //SequenceInputStream只能接收枚举对象,拼接的序列流对象    FileOutputStream fos=new FileOutputStream("4.txt");        byte[] buf=new byte[1024];    int len=0;    while((len=sis.read(buf))!=-1){      fos.write(buf,0,len);    }    fos.close();    sis.close();      }}