File类的层级遍历 与 字节流

File类

// 创建一个File对象
File file = new File("/User/lna/Desktop/a/haha.txt");

获取文件长度的方法(获取的是文件的字节数)

file.length();  // 返回一个long型数据

计算文件夹大小---遍历文件夹里面所有的文件

public static long getLen(File file) {
		long sum = 0;
		File[] files = file.listFiles();
		for (File subfile : files) {
			// 判断是不是文件夹
			// 是文件夹 继续遍历
			// 不是文件夹(是文件) 计算大小 加到sum
			if (subfile.isDirectory()) {
				sum = sum + getLen(subfile);
			} else {
				sum = sum +subfile.length();
			}
		}
		return sum;
	}

判断是不是文件夹路径 不是则重新输入路径

public static File getDir () {
	System.out.println("请输入文件夹路径");
	Scanner scanner = new Scanner(System.in);
		
	while (true) {
		String string = scanner.nextLine();
		File file = new File(string);
		if (file.isDirectory()) {
			// 是文件夹 
			return file;
		} else {
			// 不是文件夹
			System.out.println("不是文件夹路径,请重新输入");
		}
	}	
}

删除文件夹的方法

注意: 删除时 文件夹必须是空的

public static void delFile(File file) {
	File[] files = file.listFiles();
	// 遍历
	for (File subfile : files) {
		// 判断是不是文件
		if (!subfile.isDirectory()) {
			// 不是文件夹 直接删除
			subfile.delete();
		} if (subfile.isHidden()) {
			subfile.delete();
		}else {
			// 是文件夹 继续遍历
			delFile(subfile);
		}
		}
	file.delete(); // 删除该文件夹文件夹
}

输入一个文件夹路径 按层级关系打印

// 遍历文件夹 按层级打印
public static void printFile(File file,int level) {
	// 循环出要打印的"*"
	String string ="";
	for (int i = 0; i < level; i++) {
		string = string + "****";
	}
	// 获取所有文件
	File[] files = file.listFiles();
	for (File subfile : files) {
		if (!subfile.isHidden()) {
			// 不是隐藏文件 直接打印名字
			System.out.println(string + subfile.getName());
		} if (subfile.isDirectory()) {
			// 是文件夹 继续遍历
			printFile(subfile,level + 1);	
		}		
	} 
}

输入一个文件夹路径 用map集合 记录其中类型出现的次数  如: txt 5


获取文件类型的方法

1. split

通过分割文件名 获取文件类型

String name = file.getName();

String[] s = name.split("\\.");   注意正则

String type = s[1];  获取类型 

2. 

int index = name.lastIndexOf(".");

String type = name.substring(index+1);

public static void getFileNumByMap(HashMap map , File file) {
    // 找出所有文件
    File[] files = file.listFiles();
    for (File subFile : files) {
	    if (subFile.isFile()) {
		// 是文件
		// 使用map 记录类型
		String name = subFile.getName();
		// 获取文件的类型
		String[] split = name.split("\\.");
		// 得到类型
		String type = split[1];
				
		/*int index = name.lastIndexOf(".");   // 另一获取类型方法
		String type = name.substring(index+1);*/
				
		// 记录
		if (!map.containsKey(type)) {  // 之前不存在
			map.put(type, 1);
		} else {
			// 用key取对应的value     // 之前已经有同类型
			Integer integer = map.get(type);
			integer = integer + 1;
			map.put(type, integer);
		}
					
	} else {
		// 是文件夹
		// 继续遍历
		getFileNumByMap(map, subFile);			
	}
    }
}
测试

public static void main(String[] args) {
	// 测试
	HashMap map = new HashMap<>();
	File file = new File("/Users/lna/Desktop/abc");
	getFileNumByMap(map, file);
	System.out.println(map);
	}

文件过滤器 FileFilter 与 FilenameFilter

FileFilter 是JDK1.2的 FilenameFilter 是JDK1.0的  都是抽象类

通过重写 accept方法 达到过滤的效果

定义一个过滤200k以上文件的过滤器

class My200FilenameFilter implements FilenameFilter {
	@Override
	public boolean accept(File dir, String name) {
		// 拼接成完成的文件
		File file = new File(dir, name);
		// 保留文件夹
		if (file.isDirectory()) {
			return true;
		}
		// 判断文件大小
		return file.length() < 200 * 1024;
	}
}

FileFilter相当于是对FilenameFilter接口的一个升级

使用FileFilter接口 不用拼接文件

过滤TXT文件

class MyTxtFilter implements FileFilter {
	@Override
	public boolean accept(File pathname) {
		if (pathname.isDirectory()) {
			// 是文件夹 直接保存到数组中
			return true;
		}
		
		// 判断一下后缀Txt
		boolean b = pathname.getName().endsWith("txt"); 
		return b;
	}	
}

字节流

字节流: 以字节为单位 进行数据的传输

流是输入还是输出 是以参照物来衡量的

参照物为你此时的程序

输出流: 写文件  (程序 --> 文件)

输入流: 读文件  (文件 --> 程序)


OutputStream 字节输出流

InputStream 字节输入流

这两个抽象类 是所有字节流的父类(超类super)


写文件的步骤  

1.创建要绑定的文件

2.创建输出流 并绑定文件

3.写入文件

// 创建一个File(给输出流 绑定一个输出的文件)

// 给出的路径可以没有该文件(系统会帮你创建出来)

File file = new File("User/lna/Deskyop/Test/pratice.txt");

// 创建字节输出流 绑定文件

FileOutputStream fos = new FileOutputStream(file);

// 写文件

fos.write(49);

fos.write(48);

fos.write(65);

注意: 流这块出现异常 全是抛的IOException

传入int值的方法时 是按ascii码输入 一次写入一个字节

创建一个字节数组 写入文件

// 创建一个字节数组
byte[] b = {66,67,68,69};  // BCDE
fos.write(b);
// 直接写字符串
// 字符串转字节数组  getBytes();
// 字节数组转字符串  字符串的构造方法
fos.write("wanglong".getBytes());
		
fos.write(b, 1, 2);
// 关闭资源
fos.close();

注意 : 最后要关闭资源

读文件 

字节输入流 InputStream

创建字节输入流 绑定文件

File file = new File("/Users/lna/Desktop/sw/mingwei.txt");
FileInputStream fis = new FileInputStream(file);
// 读文件
	int num = fis.read();
	System.out.println((char)num);
	num = fis.read();
	System.out.println((char)num);
	num = fis.read();
	System.out.println((char)num);
	num = fis.read();
	System.out.println((char)num);
	num = fis.read();
	System.out.println((char)num);
	num = fis.read();
	// 如果读取到文件最后没有字符了 返回-1
	System.out.println(num);
	
	// 关闭资源
	fis.close();

循环读取文件的方法

public static void fun2(FileInputStream fis) throws IOException {
		// 循环读取(一次只能读一个字节)
		int num = fis.read();
		while (num != -1) {
			System.out.println((char)num);
			num = fis.read();	
		}
		fis.close();
	}

例:

一次读取多个字节

创建一个空的字节数组 长度为2

利用空的字节数组 作为缓冲区

先把文件中的字节读进数组中

一次读取两个字节 提高效率(一般一次1kb = 1024b)

// 循环读 多个字节
byte[] b = new byte[2];
int len = 0;
while ((len = fis.read(b)) != -1) {
	// 直接使用string的构造方法 
	// 将字节数组转化成字符串
	System.out.print(new String(b, 0, len));
}
// 关闭资源
fis.close();


你可能感兴趣的:(File类的层级遍历 与 字节流)