【无标题】

Lambda

一、使用Lambda必须具有接口 且要求接口中有且仅有一个抽象方法
二、有且仅有一个抽象方法的接口称为函数式接口
三、Lambda表达式的标准格式: 一些参数、一个箭头、一段代码
四、格式:(参数列表)->{一些重写方法的代码};

解释说明格式:
():接口中抽象方法的参数列表 没有参数 就空着 有参数就写出参数 多个参数使用逗号分隔
->:传递的意思 把参数传递给方法体{}
{}:重写接口的抽象方法的方法体

五、Lambda表达式是可以推导 可以省略的 凡是根据上下文推导出来的内容 都可以省略书写

可以省略的内容:

  1. (参数列表):括号中参数列表的数据类型 可以省略不写
  2. (参数列表):括号中的参数如果只有一个 那么类型和()都可以省略
  3. (一些代码):如果{}中的代码只有一行 无论是否有返回值 都可以省略{} return 分号。【注】:要省略{} return 分号必须一起省略

六、题目:给定一个厨子cook接口 内含唯一的抽象方法makefood 且无参数 无返回值 使用Lambda的标准格式调用invokeCook方法 打印输出“吃饭啦!

public class LambdaClass {
	public static void main(String[] args) {
		//使用Lambda表达式 简化匿名内部类的书写
		invokeCook(()->{
			System.out.println("吃饭了!");
		});
	}
	
	//定义一个方法 参数传递Cook接口 方法内部调用Cook接口中的方法makeFood
	public static void invokeCook(Cook cook) {
		cook.makeFood();
	}
}
public interface Cook {
	//定义无参数无返回值的方法makeFood
	public abstract void makeFood();
}

Lambda表达式有参数有返回值的练习

需求:使用数组存储多个Person对象 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序

import java.util.Arrays;
import java.util.Comparator;
public class LambdaArrays {
	public static void main(String[] args) {
		//使用数组存储多个Person对象
		Person[] arr = {
				new Person("柳岩",38),new Person("迪丽热巴",18),new Person("古力娜扎",19),
		};
		//对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
//		Arrays.sort(arr,new Comparator<Person>() {
//			@Override
//			public int compare(Person o1, Person o2) {
//				return o1.getAge() - o2.getAge();
//			}	
//		});
		
		//使用Lambda表达式 简化匿名内部类
		Arrays.sort(arr,(Person o1, Person o2)->{
			return o1.getAge() - o2.getAge();
		});
		//遍历数组
		for (Person person : arr) {
			System.out.println(person);
		}
		
		System.out.println("有参数有返回值的类型:===================================================");
		
		//调用invokeCalc方法 方法的参数是一个接口 可以使用匿名内部类
//		invokeCalc(10, 20, new Calculator() {
//			@Override
//			public int calc(int a, int b) {
//				return a + b;
//			}
//		});
		
		//使用Lambda表达式简化匿名内部类的书写
		invokeCalc(120, 130, (int a,int b)->{
			return a + b;
		});
	}
	
	//定义一个方法 参数传递两个int类型的整数 参数传递calculator接口 方法内部调用calculator中的方法calc计算两个整数的和
	public static void invokeCalc(int a,int b,Calculator c) {
		int sum = c.calc(a, b);
		System.out.println(sum);
	}
}

public class Person {
	private String nameString;
	private int age;
	
	@Override
	public String toString() {return "Person [nameString=" + nameString + ", age=" + age + "]";}
	public Person(String nameString, int age) {
		super();
		this.nameString = nameString;
		this.age = age;
	}
	public Person() {super();}
	public String getNameString() {return nameString;}
	public void setNameString(String nameString) {this.nameString = nameString;}
	public int getAge() {return age;}
	public void setAge(int age) {this.age = age;}
}
/*
 * 给定一个计算器Calculator接口 内含抽象方法calc可以将两个int数字相加得到和 使用Lambda的标准格式调用invokeCalc方法 完成120和130的相加计算
 */
public interface Calculator {
	public abstract int calc(int a,int b);
}

递归

一、递归:指在当前方法内调用自己
二、递归分为两类:直接递归(方法自身调用自己)间接递归(A方法调用B方法 B方法调用C方法 C方法调用A方法)

【注】:

  1. 递归一定要有条件限定 保证递归能够停止下来 否则会发生栈内存溢出
  2. 在递归中虽然有限定条件 但是递归次数不能太多 否则也会发生栈内存溢出
  3. 构造方法禁止递归

三、递归的使用前提:当调用方法时 方法的主体不变 每次调用方法的参数不同 可以使用递归

public class DiGui {
	public static void main(String[] args) {
		//a();
		b(1);
	}
	
	/*
	 * 在递归中虽然有限定条件 但是递归次数不能太多 否则也会发生栈内存溢出
	 * Exception in thread "main" java.lang.StackOverflowError
	 * 
	 */
	private static void b(int i) {
		System.out.println(i);
		if (i == 20000) {
			return;//结束方法
		}
		b(++i);
	}

	/*
	 * 递归一定要有条件限制 保证递归能够停下来 否则会发生栈内存溢出
	 * Exception in thread "main" java.lang.StackOverflowError
	 * a方法会在栈内存中一直调用a方法 就会导致栈内存中有无数多个a方法 方法太多了 超出栈内存的大小 就会导致内存溢出的错误
	 * 【注】:当一个方法调用其他方法的时候 被调用的方法没有执行完毕 当前方法会一直等待调用的方法执行完毕 才会继续执行
	 */
	private static void a() {
		System.out.println("a方法!");
		a();
	}
	
	/*
	 * 构造方法禁止递归
	 * 编译报错:构造方法是创建对象使用的 一直递归会导致内存中有无数多个对象 所以直接编译就报错了
	 */
	public void Recurison() {
		//Recurison();
	}
}

java.io.File

一、java.io.File类:文件和目录路径名的抽象表示形式
二、java把电脑中的文件和文件夹(目录)封装为了一个file类 我们可以使用file类对文件和文件夹进行操作
三、我们可以使用file类的方法:创建一个文件/文件夹 删除文件/文件夹 获取文件/文件夹 判断文件/文件夹是否存在 对文件夹进行遍历 获取文件的大小
四、file类是一个与系统无关的类 任何的操作系统都可以使用这个类中的方法
五、重点:记住以下单词:file文件 directory文件夹(目录) path路径

  1. 路径:
    (1)绝对路径:是一个完整的路径 以盘符(c:d:)开始的路径。如:c:\\a.txt d:\\demo\\b.txtc:\\users\itcast\\ideaProjects\\shungyuan\\123.txt
    (2)相对路径:是一个简化的路径。相对指的是相对于当前项目的根目录(c:\\users\itcast\\ideaProjects\\shungyuan)。如果使用当前项目的根目录 路径可以简化书写:c:\\users\itcast\\ideaProjects\\shungyuan\\123.txt简化为123.txt(可以省略项目的根目录)

【注】:

  1. 路径是不区分大小写
  2. 路径中的文件名称分隔符Windows使用反斜杠/ 反斜杠是转义字符 两个反斜杠代表一个普通的反斜杠
import java.io.File;
public class FileClass {
	public static void main(String[] args) {
		/*
		 * static String pathSeparator:与系统有关的路径分隔符 为了方便 他被表示为一个字符串
		 * static char pathSeparator:与系统有关的路径分隔符
		 * static String separator:与系统有关的默认名称分隔符 为了方便 他被表示为一个字符串
		 * static char separatorChar:与系统有关的默认名称分隔符
		 */
		String pathSeparatorString = File.pathSeparator;
		System.out.println(pathSeparatorString);//;路径分隔符 windows:分号; linux:冒号:
		
		String separetorString = File.separator;
		System.out.println(separetorString);//文件名称分隔符\ Windows:反斜杠\ Linux:正斜杠\
		/*
		 * 使用File.separator时 不能因为Windows:反斜杠\ Linux:正斜杠\ 在操作路径时 就直接写:
		 * 在Windows系统:c:\develop\a\a.txt或者:
		 * 在Linux系统:c:/develop/a/a.txt
		 * 因为如果这样写的话 在Windows中可以操作 但是如果项目拿到Linux中 就不能操作了
		 * 所以 要这样写:
		 * "c:"+File.separator+"develop"+File.separator+"a"+File.separator+"a.txt"
		 */
		show01();
		//show02("c:\\","a.txt");//c:\a.txt
		show02("d:\\","a.txt");//d:\a.txt
		show03();
	}

	/*
	 *  file类的构造方法:
	 * File(String parent,String child):根据parent路径名字符串和child路径名字符串创建一个新file实例
	 * 参数:把路径分成了两个部分
	 * String parent:父路径
	 * String child:子路径
	 * 好处:
	 * 1.父路径和子路径可以单独书写 使用起来非常灵活 父路径和子路径都可以变化
	 * 2.父路径是file类型 可以使用file的方法对路径进行一些操作 再使用路径创建对象
	 */
	private static void show03() {
		File parentFile = new File("c:\\");
		File file = new File(parentFile,"hello.java");
		System.out.println(file);
	}

	/*
	 * file类的构造方法:
	 * File(String parent,String child):根据parent路径名字符串和child路径名字符串创建一个新file实例
	 * 参数:把路径分成了两个部分
	 * String parent:父路径
	 * String child:子路径
	 * 好处:父路径和子路径可以单独书写 使用起来非常灵活 父路径和子路径都可以变化
	 */
	private static void show02(String parentString,String childString) {
		File file = new File(parentString,childString);
		System.out.println(file);
	}

	/*
	 * file类的构造方法:
	 * file(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新file实例
	 * 参数:
	 * String pathname:字符串的路径名称
	 * 路径可以以文件、文件夹结尾
	 * 路径可以是相对路径 绝对路径
	 * 路径可以是存在 也可以是不存在
	 * 创建file对象 只是把字符串路径封装为file对象 不考虑路径的真假情况
	 */
	private static void show01() {
		File f1 = new File("D:\\JAVA\\source.a.txt");//不存在的文件
		System.out.println(f1);//D:\JAVA\source.a.txt
		
		File f2 = new File("D:\\JAVA\\source");//存在的文件夹
		System.out.println(f2);//D:\JAVA\source

		File f3 = new File("Day01");
		System.out.println(f3);//Day01
	}
}

删除

file类创建删除功能的方法:

  1. public boolean createNewFile():当且仅当具有该名称的文件尚不存在时 创建一个新的空文件
  2. public boolean delete():删除由此file表示的文件或目录
  3. public boolean mkdir():创建由此file表示的目录
  4. public boolean mkdirs():创建由此file表示的目录 包括任何必须但不存在的父目录
import java.io.File;
import java.io.IOException;
public class FileDelete {
	public static void main(String[] args) throws IOException {
		show01();
		show02();
		show03();
	}

	/*
	 * public boolean delete():删除由此file表示的文件或目录
	 * 此方法可以删除构造方法路径中给出的文件/文件夹
	 * 返回值:布尔值
	 * true:文件/文件夹删除成功 返回true
	 * false:文件夹中有内容 不会删除返回false 构造方法中路径不存在false
	 * 【注】:delete方法是直接在硬盘删除文件/文件夹 不走回收站 删除要谨慎
	 */
	private static void show03() {
		File f1 = new File("E:\\正片\\aaa");
		boolean b1 = f1.delete();
		System.out.println(b1);
		File f2 = new File("E:\\正片\\111\\222\\333");
		boolean b2 = f2.delete();
		System.out.println(b2);
	}

	/*
	 * public boolean mkdir():创建单级空文件夹
	 * public boolean mkdirs():创建单级空文件夹 多级空文件夹
	 * 创建文件夹的路径和名称在方法中给出(构造方法的参数)
	 * 返回值:布尔值
	 * true:文件夹不存在 创建文件夹 返回true
	 * false:文件夹存在 不会创建 返回false
	 * 【注】:此方法只能创建文件夹 不能创建文件
	 */
	private static void show02() {
		File f1 = new File("E:\\正片\\aaa");
		boolean b2 = f1.mkdir();
		System.out.println("b2:" + b2);
	
		File f2 = new File("E:\\正片\\111\\222\\333");
		boolean b3 = f2.mkdirs();
		System.out.println("b3:" + b3);//不能创建 因为只能创建单级文件夹
	}

	/*
	 * public boolean createNewFile():当且仅当具有该名称的文件尚不存在时 创建一个新的空文件
	 * 创建文件的路径和名称在方法中给出(构造方法的参数)
	 * 返回值:布尔值
	 * true:文件不存在 创建文件 返回true
	 * false:文件存在 不会创建 返回false
	 * 【注】:
	 * 1.此方法只能创建文件 不能创建文件夹
	 * 2.创建文件的路径必须存在 否则会抛出异常
	 * 
	 * public boolean createNewFile() throws IOException
	 * createNewFile声明抛出了IOException 我们调用这个方法 就必须得处理这个异常 要么throws 要么try...catch
	 */
	private static void show01() throws IOException {
		File f1 = new File("E:\\正片\\1.txt");
		boolean b1 = f1.createNewFile();
		System.out.println("b1:" + b1);
	}
}

获取

file类获取功能的方法:

  1. public String getAbsolutePath():返回此file的绝对路径名字符串
  2. public String getPath():将此file转换为路径名字符串
  3. public String getName():返回由此file表示的文件或目录的名称
  4. public long Length():返回由此file表示的文件的长度
import java.io.File;
public class FileGet {
	public static void main(String[] args) {
		show01();
		show02();
		show03();
		show04();
	}

	/*
	 * public long Length():返回由此file表示的文件的长度
	 * 获取的是构造方法指定的文件的大小 以字节为单位
	 * 【注】:文件夹是没有大小概念的不能获取文件夹的大小
	 * 如果构造方法中给出的路径不存在 那么Length方法返回0
	 */
	private static void show04() {
		File f1 = new File("E:\\正片");
		long l1 = f1.length();
		System.out.println(l1);//4096
	}

	/*
	 * public String getName():返回由此file表示的文件或目录的名称
	 * 获取的就是构造方法传递路径的结尾部分(文件/文件夹)
	 * 
	 */
	private static void show03() {
		File f1 = new File("c:\\users\\itcast\\ideaProjects\\shungyuan\\123.txt");
		String nameString = f1.getName();
		System.out.println(nameString);//123.txt

		File f2 = new File("c:\\users\\itcast\\ideaProjects\\shungyuan");
		String nameString2 = f2.getName();
		System.out.println(nameString2);//shungyuan
	}

	/*
	 * public String getPath():将此file转换为路径名字符串
	 * 获取的构造方法中传递的路径
	 */
	private static void show02() {
		File f1 = new File("c:\\users\\itcast\\ideaProjects\\shungyuan\\123.txt");
		File f2 = new File("a.txt");
		String path1 = f1.getPath();
		System.out.println(path1);//c:\ users\itcast\ideaProjects\shungyuan\123.txt
		String path2 = f2.getPath();
		System.out.println(path2);//a.txt
		
		System.out.println(f1);//c:\ users\itcast\ideaProjects\shungyuan\123.txt
		System.out.println(f1.toString());//c:\ users\itcast\ideaProjects\shungyuan\123.txt
	}

	/*
	 * public String getAbsolutePath():返回此file的绝对路径名字符串
	 * 获取的构造方法中传递的路径
	 * 无论路径是绝对的还是相对的 getAbsolutePath方法返回的都是绝对路径
	 */
	private static void show01() {
		File f1 = new File("c:\\users\\itcast\\ideaProjects\\shungyuan\\123.txt");
		String absolutePath = f1.getAbsolutePath();
		System.out.println(absolutePath);/*c:\ users\itcast\ideaProjects\shungyuan\123.txt*/
		
		File f2 = new File("a.txt");
		String absolutePath2 = f2.getAbsolutePath();
		System.out.println(absolutePath2);//D:\JAVA\source\Day19\a.txt
	}
}

遍历

file类遍历(文件夹)目录功能:

  1. public String[] list():返回一个String数组 表示该file目录中的所有子文件或目录
  2. public File[] listFile():返回一个file数组 表示该file目录中的所有子文件或目录

【注】:

  1. list方法和listFile方法遍历的是构造方法中给出的目录
  2. 如果构造方法中给出的目录的路径不存在 会抛出空指针异常
  3. 如果构造方法中给出的目录的路径不是一个目录 会抛出空指针异常
import java.io.File;
public class FileFor {
	public static void main(String[] args) {
		show01();
		show02();
	}

	/*
	 * public File[] listFile():返回一个file数组 表示该file目录中的所有子文件或目录
	 * 遍历构造方法中给出的目录 会获取目录中所有文件/文件夹 把文件/文件夹封装为file对象 多个file对象存储到file数组中
	 */
	private static void show02() {
		File file = new File("D:\\JAVA\\source");
		File[] files = file.listFiles();
		for (File f : files) {
			System.out.println(f);//连隐藏文件夹都会打印输出
		}
	}

	/*
	 * public String[] list():返回一个String数组 表示该file目录中的所有子文件或目录
	 * 遍历构造方法中给出的目录 会获取目录中所有文件/文件夹的名字 把获取到的多个名称存储到一个String类型的数组中
	 */
	private static void show01() {
		File file = new File("D:\\JAVA\\source");
		String[] arr = file.list();
		for (String fileName : arr) {
			System.out.println(fileName);//连隐藏文件夹都会打印输出
		}
	}
}

判断

file判断功能的方法:

  1. public boolean exists():此file表示的文件或目录是否实际存在
  2. public boolean isDirectory():此file表示的是否为目录
  3. public boolean isFile():此file表示的是否为文件
import java.io.File;
public class FileIs {
	public static void main(String[] args) {
		show01();
		System.out.println("判断是否为文件/文件夹:============================");
		show02();
	}

	/*
	 * public boolean isDirectory():此file表示的是否为目录
	 * 用于判断构造方法中给定的路径是否以文件夹结尾
	 * 是:true 否:false
	 * public boolean isFile():此file表示的是否为文件
	 * 用于判断构造方法中给定的路径是否以文件结尾
	 * 是:true 否:false
	 * 【注】:电脑的硬盘中只有文件和文件夹 所以两个方法是互斥的
	 * 这两个方法的使用前提:路径必须是存在的 否则都返回false
	 */
	private static void show02() {
		File f1 = new File("c:\\users\\itcast\\ideaProjects\\shungyuan\\123.txt");
		//System.out.println(f1.isDirectory());//false
		//System.out.println(f1.isFile());//false
		//因为这个文件不存在 所以都返回false 所以我们在用这两个方法时 可以先判断这个文件到底存不存在
		if (f1.exists()) {//不存在就没必要获取
			System.out.println(f1.isDirectory());//false
			System.out.println(f1.isFile());//false
		}
		
		File f2 = new File("E:\\正片");
		if (f2.exists()) {//不存在就没必要获取
			System.out.println(f2.isDirectory());//true
			System.out.println(f2.isFile());//false
		}
	}

	/*
	 * public boolean exists():此file表示的文件或目录是否实际存在
	 * 用于判断构造方法中的路径是否存在 存在:true 不存在:false
	 */
	private static void show01() {
		File f1 = new File("E:\\正片");
		System.out.println(f1.exists());//true
		File f2 = new File("c:\\users\\itcast\\ideaProjects\\shungyuan\\123.txt");
		System.out.println(f2.exists());//false
	}
}

练习

遍历打印多级目录

import java.io.File;
public class Test3 {
	public static void main(String[] args) {
		File file = new File("C:\\Users\\dc16102111\\Documents\\Tencent Files\\809476070\\FileRecv");
		getAllFile(file);
	}
	
	/*
	 * 定义一个方法 参数传递file类型的目录
	 * 方法中对目录进行遍历
	 */
	public static void getAllFile(File dir) {
		System.out.println(dir);
		File[] files = dir.listFiles();
		for (File f : files) {
			if(f.isDirectory()){//对遍历得到的file文件f进行判断 判断是否是文件夹
				getAllFile(f);//f是一个文件夹  则继续遍历这个文件夹 我们发现 getAllFile方法就是传递文件夹 遍历文件夹的方法 所以直接调用getAllFile方法即可:递归 自己调用自己
			} else{
					System.out.println(f);//f是一个文件 直接打印即可
			}
		}
	}
}

搜索文件并打印

搜索C:\Users\dc16102111\Documents\Tencent Files\809476070\FileRecv文件中.md结尾的文件 并打印输出

import java.io.File;
public class Test4 {
	public static void main(String[] args) {
		File file = new File("C:\\Users\\dc16102111\\Documents\\Tencent Files\\809476070\\FileRecv");
		getAllFile(file);
	}
	
	/*
	 * 定义一个方法 参数传递file类型的目录
	 * 方法中对目录进行遍历
	 */
	public static void getAllFile(File dir) {
		File[] files = dir.listFiles();
		for (File f : files) {
			if(f.isDirectory()){//对遍历得到的file文件f进行判断 判断是否是文件夹
				getAllFile(f);//f是一个文件夹  则继续遍历这个文件夹 我们发现 getAllFile方法就是传递文件夹 遍历文件夹的方法 所以直接调用getAllFile方法即可:递归 自己调用自己
			} else{
				//f是一个文件 直接打印即可
				//把file对象f转换为字符串对象
				//String nameString = f.getName();
				//String pathString  = f.getPath();
				String string = f.toString();
				//把字符串转换为小写 更加方便判断 比如 假设有.MD结尾的文件 也可以打印输出
				string = string.toLowerCase();
				//调用String类中的方法endsWith判断字符串是否是以.java结尾
				boolean b = string.endsWith(".md");
				//如果是 则打印输出
				if (b) {
					System.out.println(f);//f是一个文件 直接打印即可
				}
				/*以上代码可以简化为链式编程:
				if (f.getName().toLowerCase().endsWith(".md")) {
					System.out.println(f);//f是一个文件 直接打印即可
				}
				*/
			}
		}
	}
}
过滤器实现

一、搜索C:\Users\dc16102111\Documents\Tencent Files\809476070\FileRecv文件中.md结尾的文件 并打印输出,可以使用过滤器来实现。
二、在file类中有两个和ListFiles重载的方法 方法的参数传递的就是过滤器

  1. File[] listFiles(FileFilter filter)
    (1)java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器
    (2)作用:用来过滤文件 (File对象)
    (3)抽象方法:用来过滤文件的方法
    (4)boolean accept(File pathname):测试指定抽象路径名是否应该包含在某个路径名列表中

参数:File pathname:使用ListFiles方法遍历目录 得到的每一个文件对象

  1. File[] listFiles(FilenameFilter filter)
    (1)java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名
    (2)作用:用于过滤文件的方法
    (3)boolean accept(File dir,String name):测试指定文件是否应该包含在某一文件列表中

参数:

  1. File dir:构造方法中传递的被遍历的目录
  2. String name:使用ListFiles方法遍历目录 获取的每一个文件/文件夹的名称

【注】:两个过滤器接口是没有实现类的 需要我们自己写实现类 重写过滤的方法accept 在方法中自己定义过滤的规则

import java.io.File;
public class Test5 {
	public static void main(String[] args) {
		File file = new File("C:\\Users\\dc16102111\\Documents\\Tencent Files\\809476070\\FileRecv");
		getAllFile(file);
	}
		
	/*
	 * 定义一个方法 参数传递file类型的目录
	 * 方法中对目录进行遍历
	 */
	public static void getAllFile(File dir) {
		File[] files = dir.listFiles(new FileFilterImpl());//传递过滤器对象
		for (File f : files) {
			if(f.isDirectory()){//对遍历得到的file文件f进行判断 判断是否是文件夹
				getAllFile(f);//f是一个文件夹  则继续遍历这个文件夹 我们发现 getAllFile方法就是传递文件夹 遍历文件夹的方法 所以直接调用getAllFile方法即可:递归 自己调用自己
			} else{
				System.out.println(f);//f是一个文件 直接打印即可
			}
		}
	}
}

三、过滤器:创建过滤器FileFilterImpl的实现类 重写过滤方法accept 定义过滤规则

import java.io.File;
import java.io.FileFilter;
public class FileFilterImpl implements FileFilter{
	@Override
	public boolean accept(File pathname) {
		if (pathname.isDirectory()) {
			return true;
		}
		return pathname.getName().toLowerCase().endsWith(".md");
	}
}

四、必须明确两件事:

  1. 过滤器中的accept方法是谁调用的
  2. accept方法的参数pathname是什么

五、listFiles方法一共做了三件事:

  1. listFiles方法会对构造方法中传递的目录进行遍历 获取目录中的每一个文件/文件夹 把获取的每一个文件/文件夹封装为File对象
  2. listFiles方法会调用参数传递的过滤器中的方法accept
  3. listFiles方法会把遍历得到的每一个File对象 传递给accept方法的参数pathname
优化
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.jar.Attributes.Name;

public class Test6 {
	public static void main(String[] args) {
		File file = new File("C:\\Users\\dc16102111\\Documents\\Tencent Files\\809476070\\FileRecv");
		getAllFile(file);
	}
	
	/*
	 * 定义一个方法 参数传递file类型的目录
	 * 方法中对目录进行遍历
	 */
	public static void getAllFile(File dir) {
		File[] files = dir.listFiles((File d,String name) -> {
			//过滤规则 pathname是文件夹或是.java结尾的文件返回true
			return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".md");
		});
		
		for (File f : files) {
			if(f.isDirectory()){//对遍历得到的file文件f进行判断 判断是否是文件夹
				getAllFile(f);//f是一个文件夹  则继续遍历这个文件夹 我们发现 getAllFile方法就是传递文件夹 遍历文件夹的方法 所以直接调用getAllFile方法即可:递归 自己调用自己
			} else{
					System.out.println(f);//f是一个文件 直接打印即可
			}
		}
	}
}

IO流

一、内存:临时存储
二、磁盘:永久存储

  1. i:input输入(读取)把磁盘中的数据读取到内存中使用
  2. o:output输出(写入)输出:把内存中的数据写入到磁盘中保存
  3. 流:数据(字符 字节) 1个字符=2个字节 1个字节=8个二进制位

三、IO流最顶层的父类:

输入流输出流
字节流字节输入流InputStream字节输出流OutputStream
字符流字符输入流Beader字符输出流Writer

四、java.io.OutputStream:字节输出流 此抽象类是表示输出字节流的所有类的超类,

  1. 其中定义了一些子类共性的成员方法:
    (1)public void close():关闭此输出流并释放与此流相关联的任何系统资源
    (2)public void flush():刷新此输出流并强制任何缓冲的输出字节被写出
    (3)public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流
    (4)public void write(byte[] b,int off,int len):从指定的字节数组写入len字节 从偏移量off开始输出到此输出流
    (5)public abstract void write(int b):将指定的字节输出流
  2. java.io.FileOutputStream extends OutputStream
    (1)FileOutputStream:文件字节输出流
    (2)作用:把内存中的数据写入到硬盘的文件中
    (3)构造方法:
    FileOutputStream(String name):创建一个向具有指定名称的文件中写入数据的输出文件流
    FileOutputStream(File file):创建一个向指定file对象表示的文件中写入数据的文件输出流

参数:写入数据的目的

  1. String name:目的地是一个文件的路径
  2. File file:目的地是一个文件

(4)构造方法的作用:

  • 创建一个FileOutputStream对象
  • 会根据构造方法中传递的文件/文件路径 创建一个空的文件
  • 会把FileOutputStream对象指向创建好的文件

五、数据由内存写入硬盘的原理:java程序-》JVM(java虚拟机)-》os(操作系统)-》os调用写数据的方法-》把数据写入到文件中
六、字节输出流的使用步骤:

  1. 创建一个FileOutputStream对象 构造方法中传递写入数据的目的地
  2. 调用FileOutputStream对象中的方法write 把数据写入到文件中
  3. 释放资源(流的使用会占用一定的内存 使用完毕要把内存清空 提高程序的效率)
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOStream {
	public static void main(String[] args) throws IOException {
		//1.创建一个FileOutputStream对象 构造方法中传递写入数据的目的地
		FileOutputStream fos = new FileOutputStream("D:\\JAVA\\source\\Day20\\src\\a.txt");
		//2.调用FileOutputStream对象中的方法write 把数据写入到文件中
		//public abstract void write(int b):将指定的字节输出流
		fos.write(97);
		//3.释放资源(流的使用会占用一定的内存 使用完毕要把内存清空 提高程序的效率)
		fos.close();
	}
}

字节输入流

一、java.io.InputStream:字节输入流。此抽象类是表示字节输入流的所有类的超类二、定义了所有子类共性的方法:

  1. int read():从输入流中读取数据的下一个字节
  2. int read(byte[] b):从输入流中读取一定数量的字节 并将其存储在缓冲区数组b中
  3. void close():关闭此输入流并释放与该流关联的所有系统资源

三、java.io.FileInputStream extends InputStream

  1. FileInputStream:文件字节输入流
  2. 作用:把硬盘文件中的数据读取到内存中使用

四、构造方法:

  1. FileInputStream(String name)
  2. FileInputStream(File file)

参数:读取文件的数据源

  1. String name:文件的路径
  2. File file:文件

五、构造方法的作用:

  1. 会创建一个FileInputStream对象
  2. 会把FileInputStream对象指定构造方法中要读取的文件

六、读取数据的原理:java程序-》JVM-》os-》os读取数据的方法-》读取文件
七、字节输入流的使用步骤:

  1. 创建FileInputStream对象 构造方法中绑定要读取的数据源
  2. 使用FileInputStream对象中的方法read 读取文件
  3. 释放资源
import java.io.FileInputStream;
import java.io.IOException;
public class InputStream {
	public static void main(String[] args) throws IOException {
		// *  1.创建FileInputStream对象 构造方法中绑定要读取的数据源
		FileInputStream fis = new FileInputStream("D:\\JAVA\\source\\Day20\\src\\b.txt");
		// *  2.使用FileInputStream对象中的方法read 读取文件
		// * int read():读取文件中的一个字节并返回 读取到文件的末尾返回-1
//		int len = fis.read();//97
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);//每读取一次指针向后移一位 所以每写一次代码就是往后读一位 读完了返回-1
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);
//		len = fis.read();
//		System.out.println(len);//-1
//		
		/*
		 * 发现以上读取文件是一个重复的过程 所以可以使用循环优化
		 * 不知道文件中有多少字节 使用while循环 while循环结束条件:读取到-1时结束
		 * 布尔表达式(len = fis.read()) != -1的含义:
		 * 1.fis.read():读取一个字节
		 * 2.len = fis.read():把读取到的字节赋值给变量len
		 * 3.(len = fis.read()) != -1:判断变量len是否不等于-1
		 */
		int len = 0;//记录读取到的字节
		while ((len = fis.read()) != -1) {
			System.out.println(len);
		}
		fis.close();
	}
}

字节输入流一次读取多个字节的方法

一、int read(byte[] b):从输出流中读取一定数量的字节 并将其存储在缓冲区数组b
二、明确两件事:

  1. 方法的参数byte[]的作用:缓冲作用 存储每次读取到的多个字节的个数 提高了读取效率 数组的长度一般定义为1024(1kb)1024的整数倍
  2. 方法的返回值int是什么:每次读取的有效字节个数

三、当使用字节流读取中文字符时 可能不会显示完整的字符 因为一个中文字符可能占用多个字节存储
四、一个中文 在gbk编码下占用两个字节 在utf-8编码下占用三个字节

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
public class InputStreamRead {
	public static void main(String[] args) throws IOException {
		// *  1.创建FileInputStream对象 构造方法中绑定要读取的数据源
		FileInputStream fis = new FileInputStream("D:\\JAVA\\source\\Day20\\src\\b.txt");
		//2.使用FileInputStream对象中的方法read 读取文件
		// * int read(byte[] b):从输出流中读取一定数量的字节 并将其存储在缓冲区数组b中
//		byte[] bytes = new byte[2];
//		int len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		/*
//		 * String类的构造方法:
//		 * String(byte[] bytes):把字节数组转换为字符串
//		 * String(byte[] bytes,int offset,int length):把字节数组的一部分转化为字符串 offset:数组的开始索引 length:转换的字节个数
//		 */
//		//System.out.println(Arrays.toString(bytes));//[49, 48]
//		System.out.println(new String(bytes));//10
//		
//		len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		System.out.println(new String(bytes));//0A
//		
//		len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		System.out.println(new String(bytes));//BC
//		
//		len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		System.out.println(new String(bytes));//DE
//		
//		len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		System.out.println(new String(bytes));//BC
//		
//		len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		System.out.println(new String(bytes));//你
//		
//		len = fis.read(bytes);
//		System.out.println(len);//2 每次读取的字节数的个数
//		System.out.println(new String(bytes));//好
//		
//		len = fis.read(bytes);
//		System.out.println(len);//-1
//		System.out.println(new String(bytes));//好

		/*
		 * 发现以上读取是一个重复的过程 可以使用循环优化
		 * 不知道文件中有多少字节 所以使用while循环 while循环结束的条件:读取到-1结束
		 */
		byte[] bytes = new byte[1024];//存储读取到的多个字节
		int len = 0;//记录每次读取的有效字节个数
		while ((len = fis.read(bytes)) != -1) {
			//System.out.println(new String(bytes));//因为D:\\JAVA\\source\\Day20\\src\\b.txt文件中的内容没有1024个字节
			//这么多 所以输出打印的内容会有很多空格 为了改进 我们可以使用String(byte[] bytes,int offset,int length):把字节数组的一部分转化为字符串
			System.out.println(new String(bytes,0,len));
		}
		
		fis.close();//释放资源
	}
}

一次写多个字节的方法

一、public void write(byte[] b):将b.length字节从指定的字节数组写入此输出流
二、public void write(byte[] b,int off,int len):从指定的字节数组写入len字节 从偏移量off开始输出到此输出流

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
public class OutputStream {
	public static void main(String[] args) throws IOException {
		//1.创建一个FileOutputStream对象 构造方法中传递写入数据的目的地
		FileOutputStream fos = new FileOutputStream(new File("D:\\JAVA\\source\\Day20\\src\\b.txt"));
		//2.调用FileOutputStream对象中的方法write 把数据写入到文件中
		//假设要求在文件中显示100
		fos.write(49);
		fos.write(48);
		fos.write(48);
		
		/*
		 * public void write(byte[] b,int off,int len):从指定的字节数组写入len字节 从偏移量off开始输出到此输出流
		 * 一次写多个字节
		 * 如果写的第一个字节是整数(0-127) 那么显示的时候会查询ASCII表
		 * 如果写的第一个字节是负数 那第一个字节会和第二个字节  第三个字节和第四个字节……每两个字节组成一个中文显示 查询系统默认码表GBK 如果有一个单的 就查询ASCII表显示
		 */
		byte[] bytes = {65,66,67,68,69};//100ABCDE
		//byte[] bytes = {-65,-66,-67,68,69};//100烤紻E
		fos.write(bytes);
		
		/*
		 * public void write(byte[] b,int off,int len):从指定的字节数组写入len字节 从偏移量off开始输出到此输出流
		 * int off:数组的开始索引
		 * int len:写几个字节
		 */
		fos.write(bytes,1,2);//100ABCDEBC
		
		/*
		 * 写入字符的方法:可以使用String类中的方法把字符串转换为字节数组
		 * byte[] getBytes():把字符串转换为字节数组
		 */
		byte[] bytes2 = "你好".getBytes();
		System.out.println(Arrays.toString(bytes2));//[-60, -29, -70, -61]
		fos.write(bytes2);//100ABCDEBC你好
		//3.释放资源(流的使用会占用一定的内存 使用完毕要把内存清空 提高程序的效率)
		fos.close();
	}
}

追加写/续写字节

一、追加写/续写:使用两个参数的构造方法:

  1. FileOutputStream(String name,boolean append):创建一个向具有指定name的文件中写入数据的输出文件流
  2. FileOutputStream(File file,boolean append):创建一个向指向file对象表示的文件中写入数据的文件输出流

参数:

  1. String name,File file:写入数据的目的地
  2. boolean append:追加写开关
    true:创建对象不会覆盖源文件 继续在文件的末尾追加写数据
    false:创建一个新文件 覆盖源文件

二、如何换行:写换行符号

Windows:\r\n
linux:/n
mac:/r
import java.io.FileOutputStream;
import java.io.IOException;
public class OutputStreamWrite {
	public static void main(String[] args) throws IOException {
		FileOutputStream fos = new FileOutputStream("D:\\JAVA\\source\\Day20\\src\\c.txt",true);
		fos.write("你好".getBytes());//每点击一次运行 D:\\JAVA\\source\\Day20\\src\\c.txt文件就会写一次你好
		fos.write("\r\n".getBytes());//每点击一次运行 D:\\JAVA\\source\\Day20\\src\\c.txt文件就会换行写一次你好
		fos.close();
	}
}

字符输入流

一、java.io.Reader:字符输入流 是字符输入流的最顶层的父类 定义了一些共性的成员方法 是一个抽象类
二、共性的成员方法:

  1. int read():读取单个字符并返回
  2. int read(char[] cbuf):一次读取多个字符 将字符读入数组
  3. void close():关闭该流并释放与之关联的所有资源

三、java.io.FileReader extends InputStreamReader extends Reader

  1. FileReader:文件字符输入流
  2. 作用:把硬盘文件中的数据以字符的方式读取到内存中

四、构造方法:

  1. FileReader(String fileName)
  2. FileReader(File file)

参数:读取文件的数据源

  1. String fileName:文件的路径
  2. File file:一个文件

五、FileReader构造方法的作用:

  1. 创建一个FileReader对象
  2. 会把FileReader对象指向要读取的文件

六、字符输入流的使用步骤:

  1. 创建FileReader对象 构造方法中绑定要读取的数据源
  2. 使用FileReader对象中的方法read读取文件
  3. 释放资源
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class Reader {
	public static void main(String[] args) throws IOException {
		// * 1.创建FileReader对象 构造方法中绑定要读取的数据源
		FileReader fr = new FileReader("D:\\JAVA\\source\\Day20\\src\\b.txt");
		// * 2.使用FileReader对象中的方法read读取文件
		// * int read():读取单个字符并返回
//		int len = 0;
//		while ((len = fr.read()) != -1) {
//			System.out.println((char)len);
//		}
		
		//为演示第二种方法 将上述代码注释
		// * int read(char[] cbuf):一次读取多个字符 将字符读入数组
		char[] cs = new char[1024];//存储读取到的多个字符
		int len = 0;//记录的是每次读取的有效字符个数
		while ((len = fr.read(cs)) != -1) {
			/*
			 * String类的构造方法:
			 * String(char[] value):把字符数组转换为字符串
			 * String(char[] value,int offset,int count):把字符数组的一部分转换为字符串 offset数组的开始索引 count转换的个数
			 */
			System.out.println(new String(cs,0,len));
		}
		// * 3.释放资源
		fr.close();
	}
}

字符输出流

一、java.io.Writer:字符输出流 是所有字符输出流的最顶层的父类 是一个抽象类
二、共性的成员方法:

  1. void write(int c):写入单个字符
  2. void write(char[] cbuf):写入字符数组
  3. abstract void write(char[] cbuf,int off,int len):写入字符数组的某一部分 off数组的开始索引 len写的字符个数
  4. void write(String str):写入字符串
  5. void write(String str,int off,int len):写入字符串的某一部分 off字符串的开始索引 len写的字符个数
  6. void flush():刷新该流的缓冲
  7. void close():关闭此流 但要先刷新他

三、java.io.FileWriter extends OutputStreamWriter extends Writer

  1. FileWriter:文件字符输出流
  2. 作用:把内存中字符数据写入到文件中

四、构造方法:

  1. FileWriter(File file):根据给定的File对象构造一个FileWriter对象
  2. FileWriter(String fileName):根据给定的文件名构造一个FileWriter对象

参数:写入数据的目的地

  1. File file:是一个文件
  2. String fileName:文件的路径

五、构造方法的作用:

  1. 会创建一个FileWriter对象
  2. 会根据构造方法中传递的文件的路径 创建文件
  3. 会把FileWriter对象指向创建好的文件

六、字符输出流的使用步骤:

  1. 创建一个FileWriter对象 构造方法中绑定要写入数据的目的地
  2. 使用FileWriter中的方法write 把数据写入到内存缓冲区中(字符转换为字节的过程)
  3. 使用FileWriter中的方法flush 把内存缓冲区中的数据刷新到文件中
  4. 释放资源(会先把内存缓冲区中的数据刷新到文件中)

七、flush方法和close方法的区别:

  1. flush:刷新缓冲区 流对象可以继续使用
  2. close:先刷新缓冲区 然后通知系统释放资源 流对象不可以再被使用了
import java.io.FileWriter;
import java.io.IOException;
public class Writer {
	public static void main(String[] args) throws IOException {
		// * 1.创建一个FileWriter对象 构造方法中绑定要写入数据的目的地
		FileWriter fw = new FileWriter("D:\\JAVA\\source\\Day20\\src\\c.txt");
		// * 2.使用FileWriter中的方法write 把数据写入到内存缓冲区中(字符转换为字节的过程)
		// * void write(int c):写入单个字符
		fw.write(97);
		// * 3.使用FileWriter中的方法flush 把内存缓冲区中的数据刷新到文件中
		// * void flush():刷新该流的缓冲
		//fw.flush();//可以不写这条语句 写fw.close();也会先把内存缓冲区中的数据刷新到文件中
		
		// * void write(char[] cbuf):写入字符数组
		char[] cs = {'a','b','c','d','e'};
		fw.write(cs);

		// * abstract void write(char[] cbuf,int off,int len):写入字符数组的某一部分 off数组的开始索引 len写的字符个数
		fw.write(cs,1,3);
		
		// * void write(String str):写入字符串
		fw.write("传智播客");
		
		// * void write(String str,int off,int len):写入字符串的某一部分 off字符串的开始索引 len写的字符个数
		fw.write("黑马程序员",2,3);
		
		// * 4.释放资源(会先把内存缓冲区中的数据刷新到文件中)
		fw.close();
	}
}

追加续写字符

一、续写:追加写:使用两个参数的构造方法

  1. FileWriter(String fileName,boolean append)
  2. FileWriter(File file,boolean append)

参数:

  1. String fileName,boolean append:写入数据的目的地的
  2. File file,boolean append:续写开关
    true:不会创建新的文件覆盖源文件 可以续写
    false:创建新的文件覆盖源文件

二、换行:使用换行符号

Windows:\r\n
linux:/n
mac:/r
import java.io.FileWriter;
import java.io.IOException;
public class XuXieAndHuanHang {
	public static void main(String[] args) throws IOException {
		FileWriter fw =new FileWriter("D:\\JAVA\\source\\Day20\\src\\c.txt",true);
		for (int i = 0; i < 10; i++) {
			fw.write("HelloWorld" + i + "\r\n");
		}
		
		fw.close();
	}
}

文件复制练习:一读一写

一、明确:

  1. 数据源:E:\正片\DSC_0087.jpg
  2. 数据的目的地:D:\JAVA\source\Day20\src

二、文件复制步骤:

  1. 创建一个字节输入流对象 构造方法中绑定要读取的数据源
  2. 创建一个字节输出流对象 构造方法中绑定要写入的目的地
  3. 使用字节输入流对象中的方法read读取文件
  4. 使用字节输出流中的方法write 把读取到的字节写入到目的地的文件中
  5. 释放资源
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class CopyFile {
	public static void main(String[] args) throws IOException {
		// * 1.创建一个字节输入流对象 构造方法中绑定要读取的数据源
		FileInputStream fis = new FileInputStream("E:\\正片\\DSC_0087.jpg");
		// * 2.创建一个字节输出流对象 构造方法中绑定要写入的目的地
		FileOutputStream fos = new FileOutputStream("C:\\");
		//一次读取一个字节 写入一个字节的方式
		// * 3.使用字节输入流对象中的方法read读取文件
//		int len = 0;
//		while ((len = fis.read()) != -1) {
//			// * 4.使用字节输出流中的方法write 把读取到的字节写入到目的地的文件中
//			fos.write(len);
//		}
		
		//方法二:使用数组缓冲读取多个字节 写入多个字节
		byte[] bytes = new byte[1024];
		// * 3.使用字节输入流对象中的方法read读取文件
		int len = 0;//每次读取的有效字节个数
		while ((len = fis.read(bytes)) != -1) {
			// * 4.使用字节输出流中的方法write 把读取到的字节写入到目的地的文件中
			fos.write(bytes,0,len);
		}
		
		// * 5.释放资源(先关闭写的流 在关闭读的流 因为写完了肯定读完了 读完了不一定写完了)
		fos.close();
		fis.close();
	}
}

异常处理

一、在JDK1.7之前使用try catch finally处理流中的异常
二、格式:

try{
	可是会产生异常的代码
}catch(异常类变量 变量名){
	异常的处理逻辑
}finally{
	一定会执行的代码
	资源释放
}
import java.io.FileWriter;
import java.io.IOException;
public class TryCatch {
	public static void main(String[] args) {
		//提高变量fw的作用域 让finally可以使用
		//变量在定义时 可以没有值 但是使用的时候必须有值
		//fw =new FileWriter("D:\\JAVA\\source\\Day20\\src\\c.txt",true);如果执行失败 fw没有值 fw.close会报错
		FileWriter fw = null;
		try {
			//可能会产生异常的代码
			fw =new FileWriter("D:\\JAVA\\source\\Day20\\src\\c.txt",true);
			for (int i = 0; i < 10; i++) {
				fw.write("HelloWorld" + i + "\r\n");
			}
			
		} catch (Exception e) {
			//异常的处理逻辑
			System.out.println(e);
		}finally {
			//一定会执行的代码
			//如果创建对象失败了 fw的默认值是Null null是不能调用方法的 会抛出空指针异常 需要增加一个判断 不是null再把资源释放
			if (fw != null) {
				try {
					fw.close();//fw.close方法声明抛出了IOException异常对象 所以我们就得处理这个异常对象 要么try catch 要么throws
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

jdk7新特性

一、在try的后边可以增加一个(),在括号中可以定义流对象,那么这个流对象的作用域就在try中有效
二、try中的代码执行完毕 会自动把流对象释放 不用写finally
三、格式:

try(定义流对象;定义流对象...){
		可能会产生异常的代码
}catch(异常类变量 变量名){
		异常的处理逻辑
}
import java.io.FileWriter;
public class JDK7 {
	public static void main(String[] args) {
		try(FileWriter fw =new FileWriter("D:\\JAVA\\source\\Day20\\src\\d.txt",true);)
		{
			//可能会产生异常的代码
			for (int i = 0; i < 10; i++) {
				fw.write("HelloWorld" + i + "\r\n");
			}
			
		} catch (Exception e) {
			//异常的处理逻辑
			System.out.println(e);
		}
	}
}

JDK9新特性

一、try的前面可以定义流对象 try后面的()中可以直接引入流对象的名称(变量名)
二、在try代码执行完毕之后 流对象也可以释放掉 不用写finally
三、格式:

A a = new A();
B b = new B();
try(a,b){
	可能会出现异常的代码
}catch(异常类变量 变量名){
	异常的处理逻辑
}
import java.io.FileWriter;
public class JDK9 {
	public static void main(String[] args) {
		FileWriter fw =new FileWriter("D:\\JAVA\\source\\Day20\\src\\d.txt",true);
		
		try(try)//我这是JDK8 不支持这个特性
		{
			//可能会产生异常的代码
			for (int i = 0; i < 10; i++) {
				fw.write("HelloWorld" + i + "\r\n");
			}
			
		} catch (Exception e) {
			//异常的处理逻辑
			System.out.println(e);
		}
	}
}

java.util.Properties

一、java.util.Properties集合 extends Hashtable<k,v> implements Map<k,v>
二、Properties类表示了一个持久的属性集 Properties可保存在流中或从流中加载
三、Properties集合是一个唯一和IO流相结合的集合
四、可以使用Properties集合中的方法store 把集合中的临时数据持久化写入到硬盘中存储
五、可以使用Properties集合中的方法load 把硬盘中保存的文件(键值对) 读取到集合中使用
六、属性列表中每个键及其对应值都是一个字符串
七、Properties集合是一个双列集合 keyvalue默认都是字符串

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
import java.util.Set;
public class ProperttiesClass {
	public static void main(String[] args) throws IOException {
		show01();
		show02();
		show03();
	}

	/*
	 * 可以使用Properties集合中的方法load 把硬盘中保存的文件(键值对) 读取到集合中使用
	 * void load(InputStream inStream)
	 * void load(Reader reader)
	 * 参数:
	 * InputStream inStream:字节输入流 不能读取含有中文的键值对
	 * Reader reader:字符输入流 能读取含有中文的键值对
	 * 使用步骤:
	 * 1.创建Properties集合对象
	 * 2.使用Properties集合对象中的方法load读取保存键值对的文件
	 * 3.遍历Properties集合
	 * 【注】:
	 * 1.存储键值对的文件中 键与值默认的连接符号可以使用= 空格 和其他符号
	 * 2.存储键值对的文件中 可以使用#进行注释 被注释的键值对不会再被读取
	 * 3.存储键值对的文件中 键与值默认都是字符串 不用再加引号
	 */
	private static void show03() throws IOException {
		//	 * 1.创建Properties集合对象
		Properties properties = new Properties();
		//	 * 2.使用Properties集合对象中的方法load读取保存键值对的文件
		properties.load(new FileReader("D:\\JAVA\\source\\Day20\\src\\pro.txt"));
		//	 * 3.遍历Properties集合
		Set<String> set = properties.stringPropertyNames();
		for (String key : set) {
			String valueString = properties.getProperty(key);
			System.out.println(key + "=" + valueString);//在文档中 在迪丽热巴前面加上了# 读取文件的时候 就不会输出打印迪丽热巴 我不知道为啥还是会显示
		}
	}

	/*
	 * 可以使用Properties集合中的方法store 把集合中的临时数据 持久化写入到硬盘中存储
	 * void store(OutputStream out,String comments)
	 * void store(Writer writer,String comments)
	 * 参数:
	 * OutputStream out:字节输出流 不能写入中文
	 * Writer writer:字符输出流 可以写中文
	 * String comments:注释 用来解释说明保存的文件是做什么用的 不能使用中文 会产生乱码 默认是Unicode编码 一般使用" "空字符串
	 * 使用步骤:
	 * 1.创建Properties集合对象 添加数据
	 * 2.创建字节输出流/字符输出流对象 构造方法中绑定要输出的目的地
	 * 3.使用Properties集合中的方法store 把集合中的临时数据 持久化写入到硬盘中存储
	 * 4.释放资源
	 */
	private static void show02() throws IOException {
		//创建Properties集合对象 添加数据
		Properties properties = new Properties();
		properties.setProperty("赵丽颖","168");
		properties.setProperty("迪丽热巴","165");
		properties.setProperty("古力娜扎","160");

		//	 * 2.创建字节输出流/字符输出流对象 构造方法中绑定要输出的目的地
		FileWriter fw = new FileWriter("D:\\JAVA\\source\\Day20\\src\\pro.txt");
		
		//	 * 3.使用Properties集合中的方法store 把集合中的临时数据 持久化写入到硬盘中存储
		properties.store(fw, "save data");
		
		//释放资源
		fw.close();
	}

	/*
	 * 使用Properties集合存储数据 遍历取出Properties集合中的数据
	 * Properties集合是一个双列集合 key和value默认都是字符串
	 * Properties集合有一些操作字符串的特有方法
	 * Object setProperty(String key,String value):调用Hashtable的方法put
	 * String getProperty(String key):通过key找到value值 此方法相当于Map集合中的get(key)方法
	 * Set<String> stringPropertyNames():返回此属性列表中的键值 其中该键及其对应值是字符串 此方法相当于Map集合中的keySet方法
	 */
	private static void show01() {
		//创建Properties集合对象
		Properties properties = new Properties();
		//使用setProperties往集合中添加数据
		properties.setProperty("赵丽颖","168");
		properties.setProperty("迪丽热巴","165");
		properties.setProperty("古力娜扎","160");

		//使用stringPropertyNames把Properties集合中的键取出 存储到一个Set集合中
		Set<String> set = properties.stringPropertyNames();
		
		//遍历Set集合 取出Properties集合的每一个键
		for (String key : set) {
			//使用getProperty方法通过key获取value
			String valueString = properties.getProperty(key);
			System.out.println(key + "=" +valueString);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值