[Java I/O 流] 带你一起玩转 File 类的实现
写在前面
- Java I/O 流用来处理设备之间的数据传输,Java 对数据的操作是通过流的方式,Java 的 I/O 通过 java.io 包下的类和接口来支持,在 java.io 包下主要包括输入、输出两种 I/O流。
- 要想掌握 Java I/O 开发,必须清楚 I/O 的5个类的核心组成,分别是 File 类、InputStream 类、OutputStream 类、Reader 类、Writer 类,本篇将主要展开File类的相关知识。
- 阅读完本篇请跳转至[Java I/O 流] 带你一起玩转输入/输出流(下):https://blog.youkuaiyun.com/SolarL/article/details/88997787
1. File 类(磁盘操作)
<1> File 类概述
- File更应该叫做一个路径,通过File 类来进行文件的操作,创建文件或者文件夹(File 对象)传给输入/输出流来实现文件的操作。
- File 类操作的是文件和目录,无法访问文件内容本身。若需要访问内容本身,则需要使用输入/输出流。
- 从 JDK 7 开始,File 类的创建可以使用 java.nio.file.Paths 来实例化。
File file = Paths.get( "C:", "Users", "dell", "Desktop", "Java").toFile();
<2> 文件路径分隔符的区别
- 对于文件路径分隔,不同操作系统有不同的分隔方式。(Windows --> \ ; Linux / Unix --> / ) 那么问题来了,不同的操作系统有不同的文件路径分隔符,而 Java 语言的一大特性就是跨平台性,这是如何实现的与平台无关性???
- File.separator 的存在为 Java 文件路径分隔符提供了可跨平台性。
File file = new File("C:" + File.separator +
"Users" + File.separator +
"dell" + File.separator +
"Desktop" + File.separator +
"Java");
2. File 类功能实现
以下方法均可通过 API 查看实现过程。
A:构造方法
- File(String pathname):根据一个路径得到File对象
- File(String parent, String child):根据一个目录和一个子文件/目录得到File对象
- File(File parent, String child):根据一个父File对象和一个子文件/目录得到File对象
B:创建功能
- public boolean createNewFile():创建文件 如果存在这样的文件,就不创建了
- public boolean mkdir():创建文件夹 如果存在这样的文件夹,就不创建了
- public boolean mkdirs():创建文件夹,如果父文件夹不存在,会帮你创建出来
C:重命名和删除功能
- public boolean renameTo(File dest):把文件重命名为指定的文件路径
- public boolean delete():删除文件或者文件夹
- Java中的删除不走回收站。
- 要删除一个文件夹,请注意该文件夹内不能包含文件或者文件夹
D:判断功能
- public boolean isDirectory():判断是否是目录
- public boolean isFile():判断是否是文件
- public boolean exists():判断是否存在
- public boolean canRead():判断是否可读
- public boolean canWrite():判断是否可写
- public boolean isHidden():判断是否隐藏
E:获取功能
- public String getAbsolutePath():获取绝对路径
- public String getPath():获取路径
- public String getName():获取名称
- public long length():获取长度。字节数
- public long lastModified():获取最后一次的修改时间,毫秒值
- public String[] list():获取指定目录下的所有文件或者文件夹的名称数组
- public File[] listFiles():获取指定目录下的所有文件或者文件夹的File数组
案例:判断E 盘目录下是否有后缀名为 .jpg 的文件,如果有,就输出该文件的名称。
import java.io.File;
public class TestFile {
public static void main(String[] args) {
//方式一:通过 listFiles() 方法返回 File[] 数组
File dir = new File( "E:/" );
File[] subFile = dir.listFiles();
for (File file : subFile) {
if(file.isFile() && file.getName().endsWith( ".dll" )){
System.out.println(file);
}
}
}
//方式二:通过 list() 方法返回String[] 数组
public static void demo01(){
File dir = new File( "E:/" );
String[] arr = dir.list();
for (String s : arr) {
if (s.endsWith( ".dll" )) {
System.out.println( s );
}
}
}
}
3. File 类综合案例实现
案例1:按层级打印所有文件及文件夹。
import java.io.File;
import java.nio.file.Paths;
/**
* @Auther: SolarL
* @Date: 2019/3/24
* @Description: com.sunlong.file
* @version: 1.0
*/
public class FileRe {
public static void main(String[] args) {
File file = Paths.get( "C:", "Users", "dell", "Desktop", "Java" ).toFile();
findFile( file, 0 );
}
private static String space(int count) {
StringBuilder sb = new StringBuilder();
String s = " ";
for (int i = 0; i < count; i++) {
sb.append( s );
}
return sb.toString();
}
public static void findFile(File file, int count) {
if (file.isFile()) {
System.out.println( space( count ) + file.getName() );
} else {
File[] files = file.listFiles();
for (File file1 : files) {
if (file1.isFile()) {
System.out.println( space( count ) + "-|" + file1.getName() );
} else {
System.out.println( space( count ) + "+" + file1.getAbsolutePath() );
findFile( file1, count + 2 );
}
}
}
}
}
import java.io.File;
public class FileText4 {
/*
* 从键盘接收一个文件夹路径,把文件夹中的所有文件及文件夹的名字按层级打印
* */
public static void main(String[] args) {
//获取文件夹路径
File dir = FileTest.getDir();
printLev(dir, 0);
}
/*
* 按层级打印
* 1.获取所有文件及文件夹,返回的File数组
* 2.遍历数组
* 3.无论文件还是文件夹均打印
* 4.如果是文件夹,递归调用
* */
public static void printLev(File dir, int lev) {
File [] subFiles =dir.listFiles();
for (File subFile : subFiles) {
for (int i = 0; i <= lev; i++) {
System.out.print("\t");
}
System.out.println(subFile);
if (subFile.isDirectory()) {
printLev( subFile, lev+1 );
}
}
}
}
案例2:从键盘接收一个文件夹路径,统计该文件夹大小。
import java.io.File;
import java.util.Scanner;
public class FileTest {
public static void main(String[] args) {
File dir = getDir();
System.out.println(countDirSize( dir ));
}
//从键盘输入接收一个文件夹路径,统计该文件夹的大小
/*从键盘输入接收一个文件夹路径
* 1.创建录入对象
* 2.定义一个无线循环
* 3.将键盘录入的结果存储并封装成File对象
* 4.对File对象进行判断
* 1>如果录入不存在,给予提示
* 2>如果录入文件路径,给予提示
* 3>如果是文件夹路径,直接返回
* */
public static File getDir(){
//从键盘输入接收一个文件夹路径
Scanner sc = new Scanner( System.in );
System.out.println("请录入文件夹路径:");
while(true){
String line = sc.nextLine();
File file = new File( line );
if(!file.exists()){
System.out.println("录入路径不存在,请重新录入文件夹路径:");
}else if(file.isFile()){
System.out.println("录入路径是文件路径,请重新录入文件夹路径:");
}else if(file.isDirectory()){
return file;
}
}
}
//统计该文件夹的大小
/*
* 1.定义一个求和变量
* 2. 获取该文件夹下所有文件和文件夹listFiles
* 3.遍历数组
* 4.判断是文件就计算大小并累加
* 5.判断是文件夹,递归调用
* */
public static long countDirSize(File dir){
long sum = 0;
File [] subFiles = dir.listFiles();
for (File subFile : subFiles) {
if (subFile.isFile()){
sum = sum + subFile.length();
}else {
sum = sum + countDirSize( subFile );
}
}
return sum;
}
}
案例3:从键盘接收一个文件夹路径,删除该文件夹。
import java.io.File;
public class FileText2 {
//从键盘接收一个文件夹路径,删除该文件夹
public static void main(String[] args) {
//从键盘接收一个文件夹路径
File dir = FileTest.getDir();
deleteFileDir( dir );
}
//删除该文件夹
/*
* 1.获取该文件夹下所有文件和文件夹
* 2.遍历数组
* 3.判断文件直接删除
* 4.如果是文件夹,递归调用
* 5.循环结束,删除文件夹(文件夹只有在空的情况下才能删除成功,无法直接删除有文件的文件夹)
* */
public static void deleteFileDir(File dir){
File [] subFiles = dir.listFiles();
for (File subFile : subFiles) {
if (subFile.isFile()){
subFile.delete();
}else if (subFile.isDirectory()){
deleteFileDir( subFile );
}
}
dir.delete();
}
}
由于篇幅过长不利于读者阅读,故本篇只介绍了File 类的各种实现方式。
未完待续…
阅读完本篇请跳转至 [Java I/O 流] 带你一起玩转输入/输出流(下)继续阅读:https://blog.youkuaiyun.com/SolarL/article/details/88997787