Appearance
Java IO - 01 前置知识之File类
本文主要介绍java.io.File类相关知识。File代表了操作系统上的文件或文件夹(目录)。
1. 创建File对象
File类提供了以下四个构造方法创建对象:
public File(String pathname):通过路径创建对象;public File(String parent, String child):通过父路径和子路径创建对象;public File(File parent, String child):通过File父对象和子路径创建对象;public File(URI uri):通过URI创建对象;
1.1 相对路径和绝对路径
绝对路径是从文件系统的根目录开始的完整路径。它提供了从根目录到目标文件或目录的完整路径信息。
在在macOS或Linux操作系统中,绝对路径以
/开始,例如/home/a.txt;在Windows系统中,绝对路径以盘符开始,例如C:/demo.txt;相对路径是从当前工作目录开始的路径。它提供了从当前工作目录到目标文件或目录的路径信息。
在路径的表示中,有两个特殊符号表示特别的含义:
.表示当前目录;..表示父目录;
两个符号在相对路径和绝对路径中都可以使用。
以下是使用相对路径和绝对路径来创建File对象的示例(以macOS系统为例):
java
// 示例一:以绝对路径表示文件夹
File f1 = new File("/Users/smz/projects/demo/java_demo");
// 示例二:以绝对路径表示文件
File f2 = new File("/Users/smz/projects/demo/java_demo/a.txt");
// 示例三:在绝对路径中使用特殊符号
File f3 = new File("/Users/smz/projects/demo/java_demo/..");
// 实际表示/Users/smz/projects/demo文件夹
// 示例四:以相对路径表示当前项目工程路径
File f4 = new File("");
File f5 = new File(".");我们也可以使用File表示不存在的文件或目录,例如:
java
File f = new File("/xxx/non_exist.txt");所以File类中提供了exists()方法表示该文件或目录是否存在。
Java
System.out.println(f.exists());当我们想输出文件路径时,File类提供了相关方法:
getCanonicalPath()方法用于获取文件或目录的规范路径(Canonical Path)。规范路径是指文件系统中唯一标识文件或目录的路径,它消除了路径中的冗余部分,如.和..,并解析为绝对路径。getAbsolutePath()方法获取文件或目录的绝对路径,它不会消除路径中的冗余部分(如.和..)。
1.2 URI、URL和URN
TIP
URI是抽象的资源标识,而URL和URN是具体的资源标识实现。
1.2.1 URI (Uniform Resource Identifier)
URI 是统一资源标识符(Uniform Resource Identifier)的缩写,它是一个用于标识某一互联网资源名称的字符串。URI 可以用来标识资源的位置或名称,或者两者兼有。
URI 的一般格式为:
scheme:[//authority]path[?query][#fragment]- scheme:协议类型,如
http、https、ftp、file等。 - authority:通常包括主机名和端口号,如
www.example.com:8080。 - path:资源路径,如
/index.html。 - query:查询参数,如
?key=value。 - fragment:锚点,如
#section1。
1.2.2 URL (Uniform Resource Locator)
URL 是统一资源定位符(Uniform Resource Locator)的缩写,它是 URI 的一个子集,用于标识资源的位置。URL 通常包含协议、主机名、端口号、路径、查询参数和锚点。
例如:
http://www.example.com/index.html?name=Kimi#section1ftp://ftp.example.com/downloads/file.zip
1.2.3 URN (Uniform Resource Name)
URN 是统一资源名称(Uniform Resource Name)的缩写,它是 URI 的另一个子集,用于标识资源的名称,而不是位置。URN 通常用于标识资源的唯一名称,而不依赖于资源的具体位置。
URN 的格式通常以 urn: 开头,后跟具体的命名空间和资源名称。
urn:<namespace>:<specific-name>示例:
urn:isbn:0451450523(标识一本书的 ISBN 号)
1.3 资源目录
在maven项目中,资源文件默认位置如下:
- 主代码资源文件:
src/main/resources - 测试代码资源文件:
src/test/resources
在项目构建时(如执行 mvn package),src/main/resources 下的文件会被复制到 target/classes 目录中,并**合并到类路径(classpath)**下。同理,src/test/resources 下的文件会复制到 target/test-classes 中,仅在测试时可用。
由于资源文件会被打包到 JAR/WAR 的类路径根目录下,因此代码中应使用 相对类路径 的路径表示方式。
getResource("/")中的/表示类路径的根目录(即target/classes)。ClassLoader.getResource("")不需要前导/,直接使用相对路径。
java
URL resource = FileTest.class.getClassLoader().getResource("");
System.out.println(resource);
URL resource1 = FileTest.class.getResource("");
System.out.println(resource1);结果如下:
txt
file:/Users/smz/projects/demo/java_demo/target/classes/
file:/Users/smz/projects/demo/java_demo/target/classes/com/lee/bio/如果在maven项目中需要访问资源目录中的资源,需要使用相对类路径的表示方法,不应该使用相对路径或绝对路径。
java
URL resource = FileTest.class.getClassLoader().getResource("data.txt");
File file = new File(resource.getPath());2. 路径分隔符
在File类中,提供了两个静态属性:separator和pathSeparator。
File.separator:表示单个路径中的目录分隔符,用于分隔文件路径中的不同层级目录。在Windows平台下是\,在Linux或macOS下是/。例如:
java
String path = "data" + File.separator + "config" + File.separator + "app.properties";
// Windows: data\config\app.properties
// Linux: data/config/app.propertiesFile.pathSeparator:表示多个路径之间的分隔符,用于分隔环境变量(如 PATH、CLASSPATH)中的不同路径。在Windows下是;,在Linux或macOS下是:。例如:
java
String classpath = "/path/to/jar1" + File.pathSeparator + "/path/to/jar2";
// Windows: /path/to/jar1;/path/to/jar2
// Linux: /path/to/jar1:/path/to/jar23. 常用方法
本小节列举File类中常用的方法:
public long length():以字节数返回文件或文件夹的大小,注意,如果是文件夹,只会返回文件夹本身的大小而不包括文件夹内容的大小;public long lastModified():返回文件或文件夹最近修改时间,返回的是自1970-01-01 00:00:00经过的毫秒数,我们可以用下面的方式格式化:java// 方式一 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); simpleDateFormat.format(file.lastModified()); // 方式二 LocalDateTime.ofInstant(Instant.ofEpochMilli(file.lastModified()), ZoneId.systemDefault())public String getParent():返回文件或文件夹的父目录;public boolean isFile():判断调用对象是否为文件;public boolean isDirectory():判断调用对象是否为文件夹;public boolean exists():判断调用对象是否存在;public String getAbsolutePath():返回绝对路径(不规范的);public String getCanonicalPath():返回规范的绝对路径;public String getPath():返回创建File对象时传入的路径,例如:javaFile file = new File("/Users/smz/notes"); File file1 = new File(""); System.out.println(file.getPath()); // 结果:/Users/smz/notes System.out.println(file1.getPath()); // 结果(空格):public String getName():基于创建File对象时传入的路径,返回文件或文件夹名称,例如:javaFile file = new File("/Users/smz/notes"); File file1 = new File(""); System.out.println(file.getName()); // 结果:notes System.out.println(file1.getName()); // 结果(空格):public boolean createNewFile():创建新文件,需父目录存在;public boolean mkdir():创建单层目录(父目录必须存在);public boolean mkdirs():创建多层目录(自动创建不存在的父目录);public boolean renameTo(File dest):重命名文件或目录;public boolean delete():删除文件或空目录(非空目录返回false);public String[] list():返回目录下的文件和子目录名称数组(非目录返回null);public File[] listFiles():返回目录下的File对象数组(非目录返回null);
4. 遍历文件夹案例
本小节使用listFiles()方法来遍历文件夹,在使用listFiles()方法时,需要注意以下内容:
- 当调用对象是文件,或者路径不存在时,返回null;
- 当调用对象是空文件夹时,返回一个长度为0的数组;
- 当调用对象是一个有内容的文件夹时,将里面所有的一级文件(包含隐藏文件)和文件夹返回;
- 当调用对象是一个文件夹,但是没有权限访问该文件夹时,返回null;
java
private void listFile(File dir, int level) throws IOException {
if(dir == null || !dir.exists()){
return;
}
System.out.print(blankString(level));
System.out.println(dir.getCanonicalPath());
if(dir.isFile()){
return;
}
for (File file : dir.listFiles()) {
listFile(file, level+1);
}
}
private String blankString(int level){
StringBuilder sb = new StringBuilder();
for(int i = 0; i < level; i++){
sb.append(' ');
}
return sb.toString();
}