22_IO_第22天(File、递归)_讲义

第22天 IO
今日内容介绍
 File
 递归
第1章 File
1.1 IO概述
回想之前写过的程序,数据都是在内存中,一旦程序运行结束,这些数据都没有了,等下次再想使用这些数据,可是已经没有了。那怎么办呢?能不能把运算完的数据都保存下来,下次程序启动的时候,再把这些数据读出来继续使用呢?其实要把数据持久化存储,就需要把内存中的数据存储到内存以外的其他持久化设备(硬盘、光盘、U盘等)上。
当需要把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作。
当把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作。
因此我们把这种输入和输出动作称为IO操作。

package cn.itcast.demo;

import java.io.File;

/*
 * java.io.File
 * 	将操作系统中的文件,目录(文件夹),路径,封装成File对象
 * 	提供方法,操作系统中的内容
 *  File与系统无关的类
 *  文件File
 *  目录directory
 *  路径path
 */
public class FileDemo {
		public static void main(String[] args) {
			//File类静态成员变量
			//与系统有关的路径的分隔符
			//static String pathSeparator 与系统有关的路径分隔符,为了方便,它被表示为一个字符串
			String separator = File.pathSeparator;
			System.out.println(separator);//是一个分号,目录的分割Linux :
			
			//与系统有关的默认名称分隔符
			separator = File.separator;
			System.out.println(separator);//向右 \ 目录名称分割Linux /
		}
}

在这里插入图片描述
简单了解IO是怎么一回事之后,接下来就要进一步做系统了解。
在我们操作系统中,数据都保存在文件中,而文件存放相应的文件夹中。那么Java中是如何描述这些的呢?
1.2 File类的出现
打开API,搜索File类。阅读其描述:File文件和目录路径名的抽象表示形式。即,Java中把文件或者目录(文件夹)都封装成File对象。也就是说如果我们要去操作硬盘上的文件,或者文件夹只要找到File这个类即可。那么我们就要研究研究File这个类中都有那些功能可以操作文件或者文件夹呢?
1.3 File类的构造函数
在这里插入图片描述
 通过构造方法创建File对象,我们进行演示:

package cn.itcast.demo;

import java.io.File;

/*
 * File类的构造方法
 * 三种重载形式(都要掌握)
 */
public class FileDemo1 {
	public static void main(String[] args) {
		function();
		System.out.println();
		function_1();
		System.out.println();
		function_2();
	}
	/*
	 * File(File parent, String child) 
	 * 根据 parent 抽象路径名和 child 路径名字符串创建一个新 File 实例
	 * 传递路径,传递File类型父路径,字符串子路径
	 * 好处:父路径是File类型,父路径可以直接调用File类方法
	 */
	public static void function_2(){
		File parent = new File("d:");
		File file = new File(parent,"eclipse");
		System.out.println(file);
	}
	/*
	 * File(String parent,String child)
	 * 传递路径,传递字符串父路径,字符串子路径
	 * 好处:单独操作父路径和子路径
	 */
	public static void function_1(){
		File file = new File("d:","eclipse");
		System.out.println(file);
	}
	/*
	 * File(String pathname)
	 * 传递路径名:可以写到文件夹,可以写到一个文件
	 * c:\\abc  c:\\abc\\Demo.java
	 * 将路径封装File类型对象
	 */
	public static void function(){
		File file = new File("d:\\eclipse");
		System.out.println(file);
	}
}

在这里插入图片描述
1.4 File类创建文件功能

  • A: File类创建文件功能
    • a: public boolean createNewFile()
      • 创建文件 如果存在这样的文件,就不创建了
  • B: File类创建目录功能
    • b: 创建目录
      • public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
      • public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
  • C: File类删除功能
    • c: 删除功能
      • public boolean delete():删除文件或者文件夹
        文件和文件夹的创建删除等
        经常上面介绍,我们知道可以通过File获取到文件名称,文件路径(目录)等信息。
        接下来演示使用File类创建、删除文件等操作。
        在这里插入图片描述
package cn.itcast.demo;

import java.io.File;
import java.io.IOException;

/*
 * File类的创建和删除功能
 * 文件或者目录
 */
public class FileDemo2 {
	public static void main(String[] args) throws IOException {
		function_3();
	}
	/*
	 * File类的删除功能
	 *  boolean delete() 删除此抽象路径名表示的文件或目录 
	 *  删除的文件或者文件夹,在File构造方法中给出
	 *  删除成功返回True,删除失败返回false
	 *  
	 *  删除方法,不走回收站,直接从硬盘中删除
	 */
	public static void function_3(){
		//删除文件夹(小心如果文件夹里面还要小文件夹,直接写文件最外面名,貌似删除不掉,得写全了,才行)
		File file = new File("d:\\abc");
		boolean b = file.delete();
		System.out.println(b);
	}
	
	/*
	 * File创建文件夹功能
	 * boolean mkdir() 
	 * 创建此抽象路径名指定的目录 
	 * 创建的路径也在File构造方法中给出
	 * 文件夹已经存在,不在创建  
	 * 
	 * 推荐使用mkdirs:可以同时创建多层次文件夹
	 *  boolean mkdirs() 
                 创建此抽象路径名指定的目录,包括所有必需但不存在的父目录 
	 */
	public static void function_2(){
		File file = new File("d:\\abc\\b\\c");
		boolean b = file.mkdirs();
		System.out.println(b);
	}
	public static void function_1(){
		File file = new File("d:\\abc");
		boolean b = file.mkdir();
		System.out.println(b);
	}
	/*
	 * File创建文件的功能
	 * boolean createNewFile() 
	 * 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件 
	 * 创建的文件路径和文件名,在File构造方法中给出
	 */
	public static void function() throws IOException{
		File file = new File("d:\\a1.txt");
		boolean b = file.createNewFile();
		System.out.println(b);
	}
}

在这里插入图片描述
1.5 File类的获取
创建完了File对象之后,那么File类中都有如下常用方法,可以获取文件相关信息
在这里插入图片描述
 方法演示如下:

package cn.itcast.demo;

import java.io.File;

/*
 * File类的获取功能
 */
public class FileDemo3 {
	public static void main(String[] args) {
		function_3();
	}
	/*
	 * File类获取功能
	 * String getParent()  返回String对象
	 * File getParentFile() 返回File对象(可以继续调用File类的方法,推荐使用)
	 * 获取父路径
	 */
	public static void function_3(){
		File file = new File("d:\\eclipse\\eclipse.exe");
		File parent = file.getParentFile().getParentFile();
		System.out.println(parent);
	}
	/*
	 * File类获取功能
	 * File getAbsoluteFile()      返回File对象(推荐使用这个)
          返回此抽象路径名的绝对路径名形式 

	 * String getAbsolutePath()    返回String对象
          返回此抽象路径名的绝对路径名字符串 
          
        eclipse环境中,写的是一个相对路径,绝对位置工程根目录
	 */
	public static void function_2(){
		File file = new File("d:\\eclipse");//Windows中文件名不区分大小写  d:\eclipse
		//File file = new File("eclipse");//Windows中文件名不区分大小写  F:\workspace\day22\eclipse
		File absolute = file.getAbsoluteFile();
		System.out.println(absolute);
	}
	/*
	 * File获取功能
	 * long length()
	 * 返回路径中表示的文件大小的字节数
	 * 不是文件夹,是文件的大小
	 */
	public static void function_1(){
		File file = new File("D:\\eclipse\\eclipse.exe");
		long length = file.length();
		System.out.println(length);
	}
	/*
	 * File类的获取功能
	 * String getName()
	 * 返回路径中表示的文件或者文件夹名
	 * 获取路径中最后部分的名字
	 */
	public static void function(){
		File file = new File("D:\\eclipse\\eclipse.exe");
		String name = file.getName();
		System.out.println(name);
		//String getPath() 将此抽象路径名转换为一个路径名字符串 
		String path = file.getPath();
		System.out.println(path);
	}
}

在这里插入图片描述
1.6 listFiles()方法介绍
文件都存放在目录(文件夹)中,那么如何获取一个目录中的所有文件或者目录中的文件夹呢?那么我们先想想,一个目录中可能有多个文件或者文件夹,那么如果File中有功能获取到一个目录中的所有文件和文件夹,那么功能得到的结果要么是数组,要么是集合。我们开始查阅API。
在这里插入图片描述

package cn.itcast.demo;

import java.io.File;

/*
 * File类获取功能
 * list
 * listFiles
 */
public class FileDemo5 {
	public static void main(String[] args) {
		function();
		System.out.println();
		function_1();
		System.out.println();
		function_2();
	}
	/*
	 * static File[] listRoots()  列出可用的文件系统根
	 */
	public static void function_2(){
		//获取系统中所有的根目录
		File[] fileArr = File.listRoots();
		for(File f : fileArr){
			System.out.println(f);
		}
	}
	/*
	 * File类的获取功能
	 * File[] listFiles()  (常用)
	 * 获取到File类构造方法中封装的路径中的文件和文件夹名(遍历一个目录)
	 * 返回的是目录或者文件的全路径
	 */
	public static void function_1(){
		File file = new File("d:\\eclipse");//连隐藏的文件都给你找出来                   
		File[] fileArr = file.listFiles();
		for(File f : fileArr){
			//String s = f.toString();//这样就可以拿到String类型
			System.out.println(f);
		}
	}
	/*
	 * File类的获取功能
	 * String[] list() 
	 * 获取到File类构造方法中封装的路径中的文件和文件夹名(遍历一个目录)
	 * 返回的只有名字
	 */
	public static void function(){
		File file = new File("c:");//连隐藏的文件都给你找出来                   
		String[] strArr = file.list();
		System.out.println(strArr.length);
		for(String s : strArr){
			System.out.println(s);//按照英文字母排列,window里随你喜欢排的,正常文件夹排在前面
		}
	}
}

输出结果:

21
$Recycle.Bin
Anaconda
BIOS
Documents and Settings
Drivers
hiberfil.sys
Intel
LenovoDrivers
LenovoQMDownload
MSOCache
pagefile.sys
PerfLogs
Program Files
Program Files (x86)
ProgramData
Recovery
swapfile.sys
System Volume Information
UserGuidePDF
Users
Windows

d:\eclipse\.eclipseextension
d:\eclipse\.eclipseproduct
d:\eclipse\artifacts.xml
d:\eclipse\configuration
d:\eclipse\dropins
d:\eclipse\eclipse
d:\eclipse\eclipse.exe
d:\eclipse\eclipse.ini
d:\eclipse\eclipsec.exe
d:\eclipse\features
d:\eclipse\p2
d:\eclipse\plugins
d:\eclipse\readme

C:\
D:\
E:\
F:\

1.7 File类判断功能

  • A: File类判断功能
    • a: 方法介绍
      • boolean exists(): 判断File构造方法中封装路径是否存在
        • 存在返回true,不存在返回false
      • boolean isDirectory(): 判断File构造方法中封装的路径是不是文件夹
        • 如果是文件夹,返回true,不是文件返回false
      • boolean isFile(): 判断File构造方法中封装的路径是不是文件
        • 如果是文件,返回true,不是文件返回false
package cn.itcast.demo;

import java.io.File;

/*
 * File类的判断功能
 */
public class FileDemo4 {
	public static void main(String[] args) {
		function_1();
		System.out.println();
		function_1();
	}
	/*
	 * File类判断功能
	 * boolean isDirectory()  
	 * 判断File构造方法中是不是文件夹
	 * 如果是文件夹,返回true,不是文件返回true
	 * 
	 * boolean isFile()
	 * 判断File类构造方法中封装的路径是不是文件
	 */
	public static void function_1(){
		File file = new File("src");
		if(file.exists()){
			boolean b = file.isDirectory();
			System.out.println(b);
		}
	}
	/* File类判断功能
	 * boolean exists()
	 * 判断File构造方法中封装路径是否存在
	 * 存在返回true,不存在返回false  
	 */
	public static void function(){
		File file = new File("src");
		boolean b = file.exists();
		System.out.println(b);
	}
}

在这里插入图片描述
1.8 文件过滤器
通过listFiles()方法,我们可以获取到一个目录下的所有文件和文件夹,但能不能对其进行过滤呢?比如我们只想要一个目录下的指定扩展名的文件,或者包含某些关键字的文件夹呢?
我们是可以先把一个目录下的所有文件和文件夹获取到,并遍历当前获取到所有内容,遍历过程中在进行筛选,但是这个动作有点麻烦,Java给我们提供相应的功能来解决这个问题。
查阅File类的API,在查阅时发现File类中重载的listFiles方法,并且接受指定的过滤器。
在这里插入图片描述
在这里插入图片描述

package cn.itcast.demo11;

import java.io.File;
import java.io.FilenameFilter;

//public interface FilenameFilter
//boolean accept(File dir, String name)   
//dir - 被找到的文件所在的目录。
//name - 文件的名称

public class MyFilter implements FilenameFilter{
	public boolean accept(File dir, String name) {
		return name.endsWith(".java");
	}
}

package cn.itcast.demo11;

import java.io.File;

public class FileDemo {
	public static void main(String[] args) {
		//获取扩展名为.java所有文件
		//创建File对象
		File file = new File("e://demo");
		//获取指定扩展名的文件,由于要对所有文件进行扩展名筛选,因此调用方法需要传递过滤器
		File[] files = file.listFiles(new MyFilter());
		//遍历获取到的所有符合条件的文件
		for (File f : files) {
			System.out.println(f);
		}
	}

}

在这里插入图片描述
在查阅API时,我们发现,在listFiles(FileFilter filter) 也可以接受一个FileFilter过滤器,它和我们讲的FilenameFilter有啥区别呢?
在这里插入图片描述
在这里插入图片描述
FilenameFilter过滤器中的accept方法接受两个参数,一个当前文件或文件夹所在的路径,一个是当前文件或文件夹对象的名称。
FileFilter 过滤器中的accept方法接受一个参数,这个参数就当前文件或文件夹对象

当我们需要过滤文件名称时就可以使用FilenameFilter这个过滤器,当我们想对当前文件或文件夹进行过滤,就可以使用FileFilter ,比如需要当前目录下的所有文件夹,就可以使用FileFilter 过滤器。
在这里插入图片描述

package cn.itcast.demo1;

import java.io.File;
import java.io.FileFilter;

/*
 * 自定义过滤器
 * boolean accept(File pathname) 
        测试指定抽象路径名是否应该包含在某个路径名列表中 
 */
public class MyFilter implements FileFilter{
	/*
	 * pathname 接受到的也是文件的全路径
	 * e://demo//a.txt
	 * 对路径进行判断,如果是java文件,返回true,不是java文件,返回false
	 * 文件的后缀结尾是.java
	 *  String getName() 返回由此抽象路径名表示的文件或目录的名称
	 *  boolean endsWith(String suffix)  测试此字符串是否以指定的后缀结束
	 */
	public boolean accept(File pathname){
		System.out.println(pathname + "##############");
		//String name = pathname.getName();//获取到文件全路径最后尾部名
		return pathname.getName().endsWith(".java");
	}
}

package cn.itcast.demo1;

import java.io.File;

/*
 * File类的获取,文件获取过滤器
 * 遍历目录的时候,可以根据需要,只获取满足条件的文件
 * 遍历目录方法listFiles()重载形式
 * File[] listFiles(FileFilter filter)  接口 FileFilter
 * public interface FileFilter 用于抽象路径名的过滤器
 * 传递  FileFilter接口的实现类 
 * 自定义FileFilter
 */
public class FileDemo {
	public static void main(String[] args) {
		File file = new File("e://demo");
		File[] fileArr = file.listFiles(new MyFilter());
		for(File f : fileArr){
			System.out.println(f);
		}
	}
	
}

在这里插入图片描述
第2章 递归
在这里插入图片描述

package cn.itcast.demo2;

import java.io.File;

/*
 * 对一个目录下的所有内容,进行完全的遍历
 * 编程技巧,方法的递归调用,自己调用自己
 */
public class FileDemo {
	public static void main(String[] args) {
		File dir = new File("e://demo");
		getAllDir(dir);
	}
	/*
	 * 定义方法,实现目录的全遍历
	 */
	public static void getAllDir(File dir){
		//打印文件名
		System.out.println(dir);
		//调用方法listFiles() 对目录,dir进行遍历
		File[] fileArr = dir.listFiles();
		for(File f : fileArr){
			//判断变量f表示的路径是不是文件夹
			if(f.isDirectory()){
				//是一个目录,就要去遍历这个目录
				//本方法,getArrDir,就是给这个目录去遍历
				//继续调用getAllDir,传递他目录
				getAllDir(f);
			}else{
				//变量f表示的路径是文件,直接打印路径名
				System.out.println(f);				
			}
		}
	}
}

在这里插入图片描述
2.1 递归的概述
递归,指在当前方法内调用自己的这种现象

public void method(){
	System.out.println(“递归的演示”);
	//在当前方法内调用自己
	method();
}

递归分为两种,直接递归和间接递归。
直接递归称为方法自身调用自己。间接递归可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
2.2 递归求和计算

  • A: 递归求和计算
    • a: 题目分析
      • 1+2+3+…+(n-1)+n:求1到n的和
      • 总结规律:1到n的和等于1到(n-1)的和再加n
      • getSum(n-1)+ n
      • 递归出口:getSum(1) return 1;
        递归求阶乘
  • B: 递归求和计算
    • a: 题目分析
      • 5!=54321
      • =5*4!
      • 4!=4*3!
      • 3!=3*2!
      • 2!=2*1!
      • 1!=1
      • n!=n*(n-1)!
      • 递归出口:n*getJieCheng(n-1): getJieCheng(1) return 1;
        在这里插入图片描述
        在这里插入图片描述
package cn.itcast.demo2;
/*
 * 方法的递归调用
 * 		方法自己调用自己
 * 适合于:方法中运算的主体不变,但是运行的时候,参与的方法参数会变化
 * 但是递归调用坏处(注意):
 * 		递归一定要有出口(保证递归调用不是死循环,否则,会内存溢出),必须可让程序停下
 * 		递归次数不能过多(太多递归,内存也受不了)
 * 		构造方法(里写递归,直接不让你用),禁止递归
 */
public class RecursiveDemo1 {
	public static void main(String[] args) {
		System.out.println(getSum(100));
		System.out.println(getJieCheng(5));
	}
	/*
	 * 计算阶乘5!
	 * 5*4*3*2*1
	 */
	public static int getJieCheng(int n){
		if(1 == n){
			return 1;
		}
		return n * getJieCheng(n-1);
	}
	/*
	 * 计算1+2+3+...+100 = 5050
	 * 计算规律:
	 * 假如n=100:
	 * 	n+(n-1)+(n-2)+..
	 *  100+(100-1)+(99-1)+..1
	 */
	public static int getSum(int n){
		if(1 == n){
			return 1;
		}
		return n + getSum(n - 1);
	}
}

在这里插入图片描述
注意:递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。

package cn.itcast.demo2;
/*
 * 方法的递归调用
 * 		方法自己调用自己
 * 适合于:方法中运算的主体不变,但是运行的时候,参与的方法参数会变化
 * 但是递归调用坏处(注意):
 * 		递归一定要有出口(保证递归调用不是死循环,否则,会内存溢出),必须可让程序停下
 * 		递归次数不能过多(太多递归,内存也受不了)
 * 		构造方法(里写递归,直接不让你用),禁止递归
 */
public class RecursiveDemo {
	public static void main(String[] args) {
		a();//java.lang.StackOverflowError
	}
	public static void a(){
		a();
	}
}

在这里插入图片描述
2.3 递归计算斐波那契数列
在这里插入图片描述

package cn.itcast.demo3;
/*
 * 斐波那契数列
 */
public class FibonacciSequenceDemo {
	public static void main(String[] args) {
		System.out.println(getFBNQ(12));
	}
	/*
	 * 方法递归,计算斐波那契数列
	 */
	public static int getFBNQ(int month){
		if(1 == month){
			return 1;
		}
		if(2 == month){
			return 1;
		}
		return getFBNQ(month-1) + getFBNQ(month-2);
	}
}

在这里插入图片描述
2.4 遍历目录下的所有java文件

package cn.itcast.demo4;

import java.io.File;
import java.io.FileFilter;

public class MyJavaFilter implements FileFilter {

	@Override
	public boolean accept(File pathname) {
		//判断获取的是目录,直接返回true,让其继续遍历
		if(pathname.isDirectory()){
			return true;
		}else{
			//endsWith区分大小写
			//toLowerCase() 方法用于将大写字符转换为小写
			return pathname.getName().toLowerCase().endsWith(".java");			
		}
	}

}

package cn.itcast.demo4;

import java.io.File;

/*
 * 遍历目录,获取
 */
public class FileDemo {
	public static void main(String[] args) {
		getAllJava(new File("e:\\demo"));
	}
	/*
	 * 定义方法,实现遍历指定目录
	 * 获取目录中所有的.java文件
	 */
	public static void getAllJava(File dir){
		//调用File对象方法listFiles()获取,加入过滤器
		File[] fileArr = dir.listFiles(new MyJavaFilter());
		for(File f : fileArr){
			//对f路径,判断是不是文件夹
			if(f.isDirectory()){
				//递归进入文件夹遍历
				getAllJava(f);
			}else{
				System.out.println(f);
			}
		}
	}
}

在这里插入图片描述
第3章 总结
3.1 知识点总结
 递归: 方法定义中调用方法本身的现象
 直接递归

public void methodA(){
			methodA();
		}

 间接递归

	public void metohdB(){
			methodC();
		}
		public void methodC(){
			methodB();
		}

 递归注意实现
 要有出口,否则就是死递归
 次数不能太多,否则就内存溢出

 File: 文件和目录路径名的抽象表示形式
 构造方法:
public File(String pathname) 通过给定的文件或文件夹的路径,来创建对应的File对象
public File(String parent, String child) 通过给定的父文件夹路径,与给定的文件名称或目录名称来创建对应的File对象
public File(File parent, String child)通过给定的File对象的目录路径,与给定的文件夹名称或文件名称来创建对应的File对象

 路径的分类:
 绝对路径, 带盘盘符

E:\Workspace\day20_File\abc.txt

 相对路径, 不带盘符

day20_File\abc.txt

 注意: 当指定一个文件路径的时候,如果采用的是相对路径,默认的目录为 项目的根目录

 方法
public boolean createNewFile()创建文件
 返回值为true, 说明创建文件成功
 返回值为false,说明文件已存在,创建文件失败
public boolean mkdir() 创建单层文件夹
 创建文件夹成功,返回 true
 创建文件夹失败,返回 false
public boolean mkdirs() 创建多层文件夹
public boolean delete()
 删除此抽象路径名表示的文件或目录。
 如果此路径名表示一个目录,则该目录必须为空才能删除
public boolean isDirectory() 判断是否为文件夹
public boolean isFile() 判断是否为文件
public boolean exists() 判断File对象对应的文件或文件夹是否存在
public String getAbsolutePath() 获取当前File的绝对路径
public String getName() 获取当前File对象的文件或文件夹名称
public long length() 获取当前File对象的文件或文件夹的大小(字节)
public File[] listFiles() 获取File所代表目录中所有文件或文件夹的绝对路径

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值