java -- File类和递归

Posted _泡泡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java -- File类和递归相关的知识,希望对你有一定的参考价值。

File类

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。File类将文件,文件夹和路径封装成了对象,提供大量的方法来操作这些对象。

静态常量

// 静态常量
static String pathSeparator // 与系统有关的路径分隔符
	// Window操作系统,分隔符是分号;
	// Linux操作系统,分隔符是冒号:
static String separator // 与系统有关的名称分隔符
	// Window操作系统,名称分割符号为 \\
	// Linux操作系统,名称分隔符号为 /

绝对路径和相对路径

  • 绝对路径:从盘符(Windows)或"/"(Linux)开始的路径,这是一个完整的路径,绝对路径具有唯一性
  • 相对路径:相对于某个目录的路径,这是一个便捷的路径,开发中经常使用,java中写的相对路径, 一般都是相对于当前项目
// Windows绝对路径 Windows
String path1 = "E:\\\\study\\\\java\\\\5_projects\\\\FileClass\\\\test";
String path2 = "/opt/html/dist"
// 相对路径
String path3 = "FileClass\\\\test";

构造方法

public File(String pathname)
// 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
public File(String parent, String child)
// 从父路径名字符串和子路径名字符串创建新的 File实例
public File(File parent, String child)
// 从父抽象路径名和子路径名字符串创建新的 File实例
// 根据给定的路径 创建File对象
File file1 = new File("E:\\\\study\\\\java\\\\5_projects\\\\FileClass\\\\test");
System.out.println(file1.toString() + "\\t " + file1.getPath());
// 传入字符串的父路径 和 字符串的子路径 创建File对象
File file2 = new File("E:\\\\study\\\\java\\\\5_projects\\\\FileClass","test");
System.out.println(file2);
File file3 = new File("E:\\\\study\\\\java\\\\5_projects","\\\\FileClass\\\\test");
System.out.println(file3);
// 传入File类型的父路径 和 字符串类型的子路径
File file4 = new File(file1, "1.txt");
System.out.println(file4);

注意:

  1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
  2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。

获取某些属性

public File getAbsoluteFile() // 获取绝对路径(File类型)
public String getAbsolutePath() // 获取绝对路径(字符串类型)
public String getPath() // 返回字符串类型的路径
public String getName() // 获取文件名
public long length() // 获取文件字节数, 不存在返回0
public File getParentFile() //返回File类型的父路径
public long lastModified() // 返回最后修改时间
// 获取绝对路径(字符串类型)
System.out.println("绝对路径为: " + new File("FileClas\\\\src").getAbsoluteFile());
System.out.println(file4.getAbsolutePath());
// 获取绝对路径(File类型)
System.out.println(file4.getAbsoluteFile());
// 获取相对路径下的File对象
File file6 = new File("FileClass" + File.separator + "test" + File.separator + "2.txt");
System.out.println(file6.getAbsolutePath());

// 获取字符串类型的路径 直接打引结果相同
// 直接打印(toString)调用了getPath方法
System.out.println(file1.getPath());

// 获取文件名
System.out.println(new File("FileClass/test/1.txt").getName());

// 获取文件字节数, 不存在返回0
long fileLength = new File("FileClass/test/1.txt").length();
System.out.println(fileLength);

// 获取父路径, 返回File对象
File parentFile = new File("FileClass/test/1.txt").getParentFile();
System.out.println(parentFile);
System.out.println(parentFile.getParentFile());

// 获取最后修改时间
long lastModifyTime = new File("FileClass/test/1.txt").lastModified();
System.out.println(lastModifyTime + "\\t" + new Date(lastModifyTime));

判断的方法

public boolean exists()
// 判断路径是否存在, 存在返回true

public boolean isFile()
// 判断是否为文件 文件返回true, 目录返回false, 路径不存在也返回false

public boolean isDirectory()
// 判断是否为目录, 目录返回true, 文件返回false, 路径不存在也返回false
// 判断路径是否存在, 存在返回true
System.out.println(new File("FileClass/test/NewDir1").exists());

// 判断是否为文件 文件返回true, 目录返回false, 路径不存在也返回false
System.out.println(file6.isFile());

// 判断是否为目录, 目录返回true, 文件返回false, 路径不存在也返回false
System.out.println(new File("FileClass/test/NewDir1").isDirectory());

// 因此 判断某文件是文件/文件夹时 要先判断路径是否存在
if (file1.exists()) 
    if(file1.isFile()) 
        System.out.println("文件");
     else 
        System.out.println("目录");
    
 else 
    System.out.println("文件不存在");

创建和删除文件

public boolean createNewFile() throws IOException
// 创建文件, 成功返回true, 存在则不创建
public boolean mkdir()
// 创建单级目录, 成功返回true, 存在则不创建
public boolean mkdirs()
// 创建单/多级目录, 成功返回true, 存在则不创建
public boolean delete()
// 删除文件或空目录, 成功返回true
// 创建文件, 成功返回true, 失败返回false
System.out.println(file6.createNewFile());

// 创建目录, 成功返回true, 失败返回false
System.out.println(new File("FileClass/test/NewDir1").mkdir());
System.out.println(new File("FileClass/test/NewDir2/NewDir3/NewDir4").mkdirs());

// 删除文件 和 空目录
System.out.println(file6.delete());
System.out.println(new File("FileClass/test/NewDir1").delete());

// 创建目录
//StringBuilder sb = new StringBuilder("FileClass/test/");
//for (int i = 0; i < 200; i++) 
//    sb.append(i);
//    sb.append("/");
//
//System.out.println(new File(sb.toString()).mkdirs());
//
//删除目录
//File fileForDel = new File(sb.toString());
//do 
//    try 
//        if (Integer.parseInt(fileForDel.getName()) < 0) 
//            System.out.println("删除失败");
//            return;
//        
//     catch (NumberFormatException e) 
//        return;
//    
//    fileForDel.delete();
//    fileForDel = fileForDel.getParentFile();
// while (true);

遍历目录

public String[] list()
// 返回目录下所有文件 存放在字符串数组中

public File[] listFiles()
// 返回目录下所有文件 存放在File数组中
String[] arr = new File("FileClass/test").list();
for (String s : arr) 
    System.out.println(s);


File[] fileArr = new File("FileClass/test").listFiles();
for (File file : fileArr) 
    System.out.println(file + "\\t" + file.getName());

FileFilter接口

文件过滤器接口,此接口的实现类可以传递给方法listFiles(),实现文件的过滤功能
public boolean accept(File path):方法参数就是listFiles()方法获取到的文件或者目录的路径。如果方法返回true,表示需要此路径,否则此路径将被忽略。

File dir = new File(".\\\\ConcurrentProgramming\\\\src\\\\_5_ThreadPool");
File[] files = dir.listFiles(new FileFilter() 
    @Override
    public boolean accept(File pathname) 
        //判断如果获取到的是目录,直接放行
        if(pathname.isDirectory())
            return true;
        //获取路径中的文件名,判断是否java结尾,是就返回true
        return pathname.getName().toLowerCase().endsWith("java");
    
);
for(File file : files)
    System.out.println(file);

递归

指在当前方法内调用自己的这种现象。

public static void a()
    a();

递归求和

计算1 ~ n的和

分析:num的累和 = num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。

实现代码:

public static void main(String[] args) 
    //计算1~num的和,使用递归完成
    int num = 5;
    // 调用求和的方法
    int sum = getSum(num);
    // 输出结果
    System.out.println(sum);


public static int getSum(int num) 
    /*
    num为1时,方法返回1,
    相当于是方法的出口,num总有是1的情况
    */
    if(num == 1)
    	return 1;
    
    /*
    num不为1时,方法返回 num +(num-1)的累和
    递归调用getSum方法
    */
    return num + getSum(num-1);

递归求阶乘

阶乘:所有小于及等于该数的正整数的积。

分析:n的阶乘:n! = n * (n-1) ... 3 * 2 * 1

//计算n的阶乘,使用递归完成
public static void main(String[] args) 
    int n = 3;
    // 调用求阶乘的方法
    int value = getValue(n);
    // 输出结果
    System.out.println("阶乘为:"+ value);


public static int getValue(int n) 
    // 1的阶乘为1
    if (n == 1) 
    	return 1;

    /*
    n不为1时,方法返回 n! = n*(n-1)!
    递归调用getValue方法
    */
    return n * getValue(n - 1);

目录遍历

遍历目录下的所有文件和所有的子目录。

分析:目录遍历,无法判断多少级目录,所以在遍历需要进行判断,如果遍历到的还是目录,就要使用递归,遍历所有目录。

public static void main(String[] args)
    // 创建File对象
    show(new File("./").getAbsoluteFile());


public static void show(File dir) 
    // 获取子文件和目录
    File[] files = dir.listFiles();
    // 循环打印
    for (File file : files) 
        //判断是文件,直接输出
        if (file.isFile()) 
            System.out.println(file);
         else 
            // 是目录,继续遍历,形成递归
            show(file);
        
    

Java基础之File类和String类

File类

计算机中万物皆文件

获取File类

获取File类有三种方式[Constructor构造方法]

  • File(String pathName);

    根据对应的文件路径创建获取对应的File类对象,可以是文件,也可以是文件夹

  • File(String parent, String child);

    根据对应的父目录文件夹路径,以及子文件名或者子文件夹名,创建对应的File类对象

  • File(File parent, String child);

    根据对应的父目录文件夹File类对象,以及子文件名或者子文件夹名,创建对应的File类对象

路径

  • 相对路径

    . 当前工作目录

    … 上级目录

  • 绝对路径

分隔符

File.separatorChar

​ 根据当前系统区分不同的分隔符

创建文件和文件夹

  • boolean createNewFile();

    通过File类对象调用,创建对应File类对象中保存的路径的普通文件

    创建成功返回True,创建失败返回False

    返回False的原因:

    1. 路径不合法
    2. 对应的文件夹没有写入权限
    3. 对应当前的文件已经存在
  • boolean mkdir();

    通过File类对象调用,创建对应的File类对象中保存路径的文件夹

    创建成功返回True,创建失败返回False

    返回False的原因:

    1. 路径不合法
    2. 对应的文件夹没有写入权限
    3. 对应当前的文件夹已经存在
  • boolean mkdirs(path);

    创建一个嵌套的文件夹

  • boolean renameTo(File dest);

    通过File类对象调用,转为目标File类对象dest

    文件/文件夹移动,重命名

实例1:

package obj_file;

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


public class Demo1 {
	public static void main(String[] args) throws IOException{
		File file = new File("D:\\\\JavaCode\\\\test");
		
		// 需要抛出异常,创建文件
		File file2 = new File(file, "1.txt");
		System.out.println(file2.createNewFile());
		
		// 创建文件夹
		File file3 = new File(file, "aaa");
		System.out.println(file3.mkdir());
		
		// 创建一个嵌套文件夹
		File file4 = new File("D:\\\\JavaCode\\\\test\\\\a\\\\b\\\\c\\\\d");
		System.out.println(file4.mkdirs());
	}
}

效果:

实例2:

package obj_file;

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


public class Demo1 {
	public static void main(String[] args) throws IOException{
		File file = new File("D:\\\\JavaCode\\\\test");
		
		// 需要抛出异常,创建文件
		File file2 = new File(file, "1.txt");
		System.out.println(file2.createNewFile());
		
		// 文件重命名,相当于覆盖源文件,但是文件的创建时间和修改时间等参数不改变
		file2.renameTo(new File("D:\\\\JavaCode\\\\test\\\\test.txt"));
	}
}

修改成功:

删除文件或者文件夹

  • boolean delete();

    通过File类对象调用,删除对应的文件或者文件夹

    要求:

    1. 删除的文件或者文件夹都是直接抹掉数据,不是放入回收站
    2. 无法删除非空文件夹,文件夹中存在其他内容无法整体删除
  • void deleteOnExit();

    程序退出时删除对应的文件或者文件夹

    可用于删除程序运行过程中,留下的日志文件,缓存文件等

		File file = new File("D:\\\\JavaCode\\\\test\\\\test.txt");
		System.out.println(file.delete());
		
		File file2 = new File("D:\\\\JavaCode\\\\test\\\\a");
		file2.deleteOnExit();

文件属性判断

  • boolean isFile();

    判断是否是一个普通文件

  • boolean isDirectory

    判断是否是一个文件夹

  • boolean isAbsolute();

    判断是否使用了绝对路径

  • boolean isHidden();

    判断是否是隐藏文件

  • boolean exists();

    判断文件是否存在

package obj_file;

import java.io.File;

public class Demo2 {
	public static void main(String[] args) {
		// 判断是否是一个普通文件
		System.out.println(new File("D:\\\\JavaCode\\\\test\\\\1.txt").isFile());
		
		// 判断是否是一个文件夹
		System.out.println(new File("D:\\\\JavaCode\\\\test\\\\1.txt").isDirectory());
		System.out.println(new File("D:\\\\JavaCode\\\\test").isDirectory());
		
		// 判断是否使用了绝对路径,注意20.txt及时不存在结果也是true,只判断是否是绝对路径
		System.out.println(new File("D:\\\\JavaCode\\\\test\\\\1.txt").isAbsolute());
		System.out.println(new File("D:\\\\JavaCode\\\\test\\\\20.txt").isAbsolute());

		// 判断是否是隐藏文件
		System.out.println(new File("D:\\\\JavaCode\\\\test\\\\2.txt").isHidden());
		
		// 判断文件是否存在
		System.out.println(new File("D:\\\\JavaCode\\\\test\\\\2.txt").exists());
	}
}

获取文件属性

  • String getPath();

    获取File类对象保存的路径

  • String getName();

    获取当前File类对象中保存的文件名或者文件夹名

  • String getParent();

    获取当前File类对象对应文件或文件夹的父目录路径

  • String getAbsolutePath();

    获取当前File类对象对应文件或者文件夹的绝对路径

常用方法:

  • long lastModified();

    获取文件最后一次修改时间,返回值是一个时间戳类型,从1970年01月01日00:00:00到现在的秒数

  • long length();

    获取文件的大小,字节数

package obj_file;

import java.io.File;

public class Demo3 {
	public static void main(String[] args) {
		File file = new File("D:\\\\JavaCode\\\\test\\\\test.txt");
		
		System.out.println(file.getPath());
		System.out.println(file.getParent());
		System.out.println(file.getName());
		System.out.println(file.getAbsolutePath());
		
        // 如果找不到文件,返回时间0
		System.out.println(file.lastModified());
        // 文件夹返回0L,找不到返回0L
		System.out.println(file.length());
	}
}

package obj_file;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Demo3 {
	public static void main(String[] args) {
		File file = new File("D:\\\\JavaCode\\\\test\\\\test.txt");
		
		long lastModified = file.lastModified();
		System.out.println(lastModified);
		
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
		String format = simpleDateFormat.format(new Date(lastModified));
		
		System.out.println(format);
	}
}

列表方法

  • static File[] listRoots();

    通过File类对象调用,有且针对于Windows操作系统有效,获取当前电脑内所有根盘符对象,如果是Linux,UNIX,macos则无效

  • File[] listFiles();

    通过File类对象调用,获取当前File类对象对应文件夹下的所有子文件或者子文件夹的File类对象数组

  • String[] list();

    通过File类对象调用,获取当前File类对象对应文件夹下的所有子文件或者子文件夹的String类型文件名或者文件夹名称数组

实例:

package obj_file;

import java.io.File;

public class Demo4 {
	public static void main(String[] args) {
		File[] listRoots = File.listRoots();
		
		/*
		 * for (数据类型 变量名:数组/集合) {
		 * }
		 */
		for(File file : listRoots) {
			System.out.println(file);
		}
		
		System.out.println("--------------");
		File file = new File("D:\\\\JavaCode\\\\test");
		File[] listFiles = file.listFiles();
		for (File file2 : listFiles) {
			System.out.println(file2);
		}
		
		System.out.println("--------------");
		String[] liStrings = file.list();
		for (String string : liStrings) {
			System.out.println(string);
		}
	}
}

输出:

FilenameFilter文件名过滤器

匿名内部类实现方法:

package obj_file;

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

public class Demo5 {
	public static void main(String[] args) {
		File file = new File("D:\\\\JavaCode\\\\test");

		// 使用匿名内部类的匿名对象直接作为方法的参数
		File[] listFiles = file.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File dir, String name) {
				/*
				 * dir是当前操作的文件夹类对象 name是当前文件夹下的子文件或者子文件夹 获取对应的Java文件 1.判断是不是普通文件
				 * 2.判断当前文件夹是不是以.java结尾的
				 */
				return new File(dir, name).isFile() && name.endsWith(".java");
			}
		});

		for (File file2 : listFiles) {
			System.out.println(file2);
		}
	}
}

lambda表达式方法实现:

jdk1.8新特征

	File[] listFiles = file.listFiles((dir, name) -> 
		new File(dir, name).isFile() && name.endsWith(".java")
		);

	for (File file2 : listFiles) {
		System.out.println(file2);
	}

常用API-String

String字符串冗余问题

复习实例:

将文件按照不同的文件后缀名归类,如:Java后缀的放到Java文件夹,doc文件放到doc文件夹

package obj_file;

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

public class Demo7 {
	public static void main(String[] args) throws IOException{
		// 目标文件夹的File类对象
		File file = new File("D:\\\\JavaCode\\\\demo");
		
		// 需要创建的文件夹类对象
		File toBeCreateFile = null;
		
		// 判断file是否是文件夹,不是文件夹就退出程序
		if(!file.isDirectory()) {
			return;
		}
		
		// 当前文件夹已经完成归档,不需要再次归档
		if(new File(file,"1.lock").exists()) {
			System.out.println("已经归档完成");
			return;
		}
		
		// 当前文件夹下的所有子文件和子文件夹File类对象
		File[] listFiles = file.listFiles();
		
		// 遍历listFiles对象数组
		for (File srcFile : listFiles) {
			// 如果是文件,获取后缀名
			if(srcFile.isFile()) {
				String fileName = srcFile.getName();
				String upperSuffix = fileName.substring(fileName.lastIndexOf(".") + 1)
						.toUpperCase();
				toBeCreateFile = new File(file, upperSuffix);
			} else {
				// 如果是文件夹,则创建子文件夹最后统一移进去
				toBeCreateFile = new File(file, "subDir");
			}
			
			// 创建文件夹
			toBeCreateFile.mkdir();
            
			// 移动文件
			srcFile.renameTo(new File(toBeCreateFile, srcFile.getName()));
		}
		
		// 创建锁文件
		new File(file, "1.lock").createNewFile();
	}
}

执行效果:

String类

String比较

双等于号(==)更多的是比较地址,而.equals比较的是数值,推荐使用equals

推荐使用:

String str1 = "test"

比较方法

获取方法

  • int length();

    获取字符串长度

  • char charAt(int index);

    获取String字符串中指定下标位置的char类型字符,如果index超出有效范围,抛出异常StringIndexOutOfBoundException

  • int indexOf(char ch);

  • int indexOf(String str);

  • int indexOf(char ch, int fromIndex);

  • int indexOf(String str, int fromIndex);

    这四个方法都是获取指定元素所在的下标位置,元素可以是char类型字符,也可以是字符串,找出指定元素在字符串中第一次出现的位置,也可以通过fromIndex约束,从哪个位置开始找

  • int lastIndexOf(char ch);

  • int lastIndexOf(String str);

  • int lastIndexOf(char ch, int fromIndex);

  • int lastIndexOf(String str, int fromIndex);

    这四个方法都是获取指定元素所在的下标位置,元素可以是char类型字符,也可以是字符串,找出指定元素在字符串中最后一次出现的位置,也可以通过fromIndex约束,从哪个位置开始找

找到返回位置(从0开始),找不到返回负数

实例:

package obj_string;

public class Demo1 {
	public static void main(String[] args) {
		String str = "ocean is a good boy";
		
		System.out.println("str的长度:" + str.length());
		System.out.println("下标为4的字符为:" + str.charAt(4));
		System.out.println("===========================================");

		System.out.println("字符o所在的位置为:" + str.indexOf("o"));
		System.out.println("字符串oo所在的位置为:" + str.indexOf("oo"));
		System.out.println("字符o从5开始后查找第一次出现的位置为:" + str.indexOf("o", 5));
		System.out.println("字符串oo从5开始后查找第一次出现的位置为:" + str.indexOf("oo", 5));
		System.out.println("===========================================");

		System.out.println("字符o所在的位置为:" + str.lastIndexOf("o"));
		System.out.println("字符串oo所在的位置为:" + str.lastIndexOf("oo"));
		System.out.println("字符o从5开始后查找最后一次出现的位置为:" + str.lastIndexOf("o", 5));
		System.out.println("字符串oo从5开始后查找最后一次出现的位置为:" + str.lastIndexOf("oo", 5));
		System.out.println("字符串o从5开始后查找最后一次出现的位置为:" + str.lastIndexOf("o", 5));
		System.out.println("===========================================");
		
		System.out.println("字符串a从5开始后查找第一次出现的位置为:" + str.lastIndexOf("a", 5));

	}
}

注意:lastIndexOf(String str, int fromIndex);加了fromIndex就是从后往前数

判断方法

  • boolean endsWith(String str);

    判断当前字符串是不是以指定字符串结尾

  • boolean isEmpty();

    判断字符串是否为空 ""空串

    JDK1.6之后,null不能读取,不能写入,不能调用方法

  • boolean equals(Object obj);

    继承重写Object类内的方法,完成字符串要求的比较方法

  • boolean equalsIgnoreCase(String str);

    不区分大小写比较

  • boolean contains(String str);

    判断字符串是否存在

package obj_string;

public class Demo2 {
	public static void main(String[] args) {
		String str = "ocean";
		
		System.out.println("str.isEmpty:" + str.isEmpty());
		System.out.println("str.endsWith:" + str.endsWith("an"));
		System.out.println("abcdefg".equals("abcdefg"));
		System.out.println("AbCdefg".equalsIgnoreCase("abcdefg"));
		System.out.println(str.contains("an"));
	}
}

转换方法

数组转换成字符串

  • String(char[] arr);

    使用字符数组中内容创建一个字符串对象

  • String(char[] arr, int offset, int length)

    使用字符数组中内容创建一个字符串对象,offset是从char类型数组中指定下标位置开始获取数据,获取的数据长度为length

  • static String valueOf(char[] arr);

    通过类名调用的静态方法,实际执行的是String(char[] arr, int offset, int length);

  • char[] toCharArray();

    返回当前字符串对应的字符数组

package obj_string;

public class Demo3 {
	public static void main(String[] args) {
		char[] arr = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
		
		String str1 = new String(arr);
		System.out.println(str1);
		
		String str2 = new String(arr, 2, 5);
		System.out.println(str2以上是关于java -- File类和递归的主要内容,如果未能解决你的问题,请参考以下文章

Java基础之File类和String类

Java全栈JavaSE:25.File类和IO流

java递归删除File

File类和输入输出流体系基础

Java——File类,递归

Java之File与递归