一、练习

深度遍历文件夹

深度遍历很自然而然想到递归,而递归就很自然的想到其实现的底层算法是栈

对指定目录下列出所有内容(包含子目录的内容)

PS:建议不要遍历C盘

import java.io.*;

public class Main 
{
	public static void main(String[] args) throws IOException {
		
		File dir = new File("D:\\ACM集训");
		ListAllDemo(dir,0);
	}

	public static void ListAllDemo(File dir,int level) throws IOException {
		
		System.out.println(GetSpace(level)+"文件夹 : "+dir.getAbsolutePath());
		level++;//为了缩进
		//获取指定目录下当前所有文件/文件对象
		File[] files = dir.listFiles();
		for(int i =0;i<files.length;i++){
			if(files[i].isDirectory()){
				ListAllDemo(files[i],level);
			}
			else{
				System.out.println(GetSpace(level)+"文件 : "+files[i].getAbsolutePath());
			}
		}
	}

	public static String GetSpace(int level) {
		// TODO Auto-generated method stub
		StringBuilder sb = new StringBuilder();
		for(int i = 0;i<level;i++)
		sb.append("    ");
		return sb.toString();
	}
}



删除目录


import java.io.*;

public class Main 
{
	public static void main(String[] args) throws IOException {
		
		File dir = new File("D:\\ACM集训1");
		//dir.delete(dir);如果文件里有内容,是不能从根目录删除的,必须从里往外删
		DeleteDemo(dir);
	}

	public static void DeleteDemo(File dir) {
		
		File[] files = dir.listFiles();
		for(File f: files){
			if(f.isDirectory()){
				DeleteDemo(f);
			}
			else{
				System.out.println(f.getAbsolutePath()+" : "+f.delete());//删除文件
			}
		}
		System.out.println(dir.getAbsolutePath()+":"+dir.delete());//删除文件夹
	}
	
}



二、Properties集合

API文档解释:Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。


特点:

该集合中的键和值都是字符串类型

集合中的数据可以保存到流中,或从流中获取

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


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

public class Main 
{
	public static void main(String[] args) throws IOException {
	
		PropertiesDemo();
	}

	public static void PropertiesDemo() {
		//存
		Properties pro = new Properties();
		pro.setProperty("a", "1");
		pro.setProperty("b", "2");
		pro.setProperty("c", "3");
		pro.setProperty("d", "1");
		
		//修改
		pro.setProperty("c", "6");
		//取
		Set<String> name = pro.stringPropertyNames();
		//stringPropertyNames():返回此属性列表中的键集,其中该键及其对应值是字符串,
		//如果在主属性列表中未找到同名的键,则还包括默认属性列表中不同的键。
		for(String s : name){
			String value = pro.getProperty(s);
			//getProperty():用指定的键在此属性列表中搜索属性。
			System.out.println(s+" : "+value);
		}
	}
}



三、Properties集合和流对象相结合

1.list方法:

将属性列表输出到指定的输出流。此方法对调试很有用。


public static void PropertiesDemo() {
		
		Properties pro = new Properties();
		pro.setProperty("a", "1");
		pro.setProperty("b", "2");
		pro.setProperty("c", "3");
		pro.setProperty("d", "1");
		
		pro.list(System.out);
	}



调用此方法随时都可以看到Properties集合存储的是什么

和 System.getProperties(),差不多


2.store方法

这方法就体现了Properties集合特点中的持久化,将集合中的信息储存起来



public void store(OutputStream out, String comments)throws IOException

以适合使用

load(InputStream) 方法加载到

Properties 表中的格式,将此

Properties 表中的属性列表(键和元素对)写入输出流。 




out - 输出流。

comments - 属性列表的描述。


而save方法已经过时了。


public static void PropertiesDemo() throws IOException {

		Properties pro = new Properties();
		pro.setProperty("a", "1");
		pro.setProperty("b", "2");
		pro.setProperty("c", "3");
		pro.setProperty("d", "1");
		
		//将Properties集合中的信息持久化的储存到文件中,需要关联输出流
		
		FileOutputStream fos = new FileOutputStream("tep.txt");
		//集合数据存储到文件中,store
		pro.store(fos, "name and age");//这个方法不建议是使用中文信息
	}



3.load方法


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


public static void PropertiesDemo() throws IOException {

		//集合中的数据来自文件,而不是我们存放的
		Properties pro = new Properties();//注意必须保证文件中的数据是键值对
		
		FileInputStream fis = new FileInputStream("tep.txt");
		
		//使用load方法
		pro.load(fis);
		pro.list(System.out);
	}



其原理



public static void Myload() throws IOException {

		Properties pro = new Properties();
		BufferedReader br = new BufferedReader(new FileReader("tep.txt"));
		String str = null;
		while((str = br.readLine())!=null){
			if(str.startsWith("#"))continue;//因为文件中有些配置信息不是含“=”的
			String[] arr = str.split("=");
			//System.out.println(arr[0]+":"+arr[1]);
			pro.setProperty(arr[0], arr[1]);
		}
		pro.list(System.out);
		br.close();
		
	}



4.修改已有的配置文件中的信息

1.读取这个文件

2.将文字中的键值信息存储到集合中

3.通过集合修改信息

4.在通过流将修改后的信息存储到文件中


public static void PropertiesDemo() throws IOException{

		File file = new File("tep.txt");
		if(!file.isFile()){
			file.createNewFile();
		}
		FileReader fr = new FileReader("tep.txt");
		//FileWriter fw = new FileWriter(file);如果放在这,就会新建一个文件覆盖file,最后文件存的c=3
		Properties pro = new Properties();
		pro.load(fr);
		//pro.list(System.out);
		pro.setProperty("c", "3");
		
		//一定要改完后才关联输出流对象,不要在上面就关联
		FileWriter fw = new FileWriter(file);//流可以直接操作File对象
		pro.store(fw, "after change");
	}



四、练习


获取一个应用程序的使用次数,超过3次,给出使用次数已到请注册的信息,并不要再运行程序的信息

分析:

此需求,需要一个计数器,每次程序启动计数器进内存,次数+1,退出程序,计数器关闭,存储到文件。

因为信心要明确,应该有名字和次数,->键值对->Map->Map+IO -> Properties


public static void PropertiesDemo() throws IOException{

		File countFile = new File("conutFile.properties");//键值对的配置信息(java)
		if(!countFile.isFile())
			countFile.createNewFile();
		FileInputStream  fis = new FileInputStream(countFile);
		Properties pro = new Properties();
		pro.load(fis);
		
		//从集合中通过键获取使用次数
		
		String value = pro.getProperty("time");
		int count = 0;//定义计数器
		if(value!=null){
			count = Integer.parseInt(value);//转换成int
			if(count>=3){
				throw new RuntimeException("使用次数已到,请注册!");
			}
		}
		count++;
		//将改变后的数据重新存储
		pro.setProperty("time", count+"");//修改
		
		FileOutputStream fos = new FileOutputStream(countFile);//关联输出流
		
		pro.store(fos, "time is");//存储到文件
		fos.close();
		fis.close();	
	}




在开发的时候就可以将这段代码封装成一个对象,在运行时,创建即可