认识文件
我们先来认识狭义上的文件(file)。针对硬盘这种持久化存储的 I/O 设备,当我们想要进行数据保存时,往往不是保存一个整体,而是独立成一个个单位进行保存,这个独立的单位就被抽象成文件的概念,就类似办公桌是上的一份份真实的文件一般。
文件除了有数据内容之外,还有一部分信息,例如文件名,文件类型,文件大小等并不作为文件的数据而存在,我们把这部分信息可以视为文件的元信息。
树形结构组织 和 目录 (N叉树)
随着文件越来越多,对文件的管理也被提上了日程,如何进行文件的组织呢,一种合乎自然地想法就出现了,就是按照层级结构进行组织 ——也就是我们数据结构中学习过的树形结构。这样,一种专门用来存放管理信息的特殊文件诞生了,也就是我们平时所谓文件夹(folder)或者目录(directory) 的概念。
文件路径(Path)
如何在文件系统中如何定位我们的一个唯一的文件就成为当前要解决的问题,但这难不倒计算机科学 家 ,因为从树形结构的角度看,树中的每个结点都可以被一条从跟根开始,一直到达的结点的路径所描述的,而这种描述方式就被称为文件的绝对路径(absolute path)。
除了可以从根节点进行路径的描述,我们可以从任意结点出发,进行路径的描述,而这种描述方式就被称为相对路径(relative path),相对于当前所在结点的一条路径。
其他知识
即使是普通⽂件 ,根据其保存数据的不同 ,也经常被分为不同的类型 ,我们⼀般简单的划分为文本文件和⼆进制⽂件 ,分别指代保存被字符集编码的⽂本和按照标准格式保存的非被字符集编码过的文件。
Windows 操作系统上 ,会按照文件名中的后缀来确定⽂件类型以及该类型文件的默认打开程序。但这个习俗并不是通⽤的 ,在 OSX、 Unix、 Linux 等操作系统上 ,就没有这样的习惯 ,⼀般不对文件类型做如此精确地分类。
文件由于被操作系统进⾏了管理 ,所以根据不同的⽤户 ,会赋予用户不同的对待该⽂件的权限 ,⼀般 地可以认为有可读、可写、可执行权限。
Windows 操作系统上 ,还有⼀类⽂件⽐较特殊 ,就是平时我们看到的快捷⽅式(shortcut),这种⽂ 件只是对真实⽂件的⼀种引⽤⽽已。其他操作系统上也有类似的概念 ,例如 ,软链接(soft link)等。
很多操作系统为了实现接⼝的统⼀性 ,将所有的 I/O 设备都抽象成了文件的概念 ,使⽤这⼀理念最为知名的就是 Unix、 Linux 操作系统 ⸺ 万物皆文件。
Java中操作文件
Java 中通过 java.io.file 类来对⼀个⽂件(包括目录) 进⾏抽象的描述。注意 ,有 File 对象,并不代表真实存在该⽂件。
File概述
先来看看 File 类中的常见属性、构造方法和方法
属性
修饰符及类型 | 属性 | 说明 |
---|---|---|
statiic String | pathSepatator | 依赖于系统的路径分隔符 ,String 类型的表示 |
static char | pathSeparatorChar | 依赖于系统的路径分隔符 ,char 类型的表示 |
public static final String pathSeparator 与系统相关的路径分隔符,为方便起见,表示为字符串。 该字符串包含单个字符,即pathSeparatorChar。 源码如下: public static final String pathSeparator = "" + pathSeparatorChar; public static final char pathSeparatorChar 与系统相关的路径分隔符。 此字段初始化为包含系统属性值path.separator的第一个字符。 此字符用于分隔作为路径列表给出的文件序列中的文件名。 在UNIX系统上,此字符为':' ; 在Microsoft Windows系统上,它是';' 。 另请参见: System.getProperty(java.lang.String) 源码如下: public static final char pathSeparatorChar = fs.getPathSeparator();
构造方法
签名 | 说明 |
---|---|
File(File parent, String child) | 根据⽗⽬录 + 孩⼦⽂件路径 ,创建⼀个新的 File 实例 |
File(String pathname) | 根据⽂件路径创建⼀个新的 File 实例 ,路径可以是绝 对路径或者相对路径 |
File(String parent, String child) | 根据⽗⽬录 + 孩⼦⽂件路径 ,创建⼀个新的 File 实 例 ,⽗⽬录⽤路径表⽰ |
方法
修饰符及返回值类型 | ⽅法签名 | 说明 |
---|---|---|
String | getParent() | 返回 File 对象的⽗⽬录⽂件路径 |
String | getName() | 返回 File 对象的纯⽂件名称 |
String | getPath() | 返回 File 对象的⽂件路径 |
String | getAbsolutePath() | 返回 File 对象的绝对路径 |
String | getCanonicalPath() | 返回 File 对象的修饰过的绝对路径 |
boolean | exists() | 判断 File 对象描述的⽂件是否真实 存在 |
boolean | isDirectory() | 判断 File 对象代表的⽂件是否是⼀个目录 |
boolean | isFile() | 判断 File 对象代表的⽂件是否是⼀ 个普通⽂件 |
boolean | createNewFile() | 根据 File 对象 ,⾃动创建⼀个空⽂件。成功创建后返回true |
boolean | delete() | 根据 File 对象 ,删除该⽂件。成功删除后返回true |
void | deleteOnExit() | 根据 File 对象 ,标注⽂件将被删除 ,删除动作会到JVM 运⾏结束时才会进⾏ |
String[] | list() | 返回 File 对象代表的⽬录下的所有 文件名 |
File[] | listFiles() | 返回 File 对象代表的⽬录下的所有 ⽂件 ,以 File 对象表⽰ |
boolean | mkdir() | 创建 File 对象代表的⽬录 |
boolean | mkdirs() | 创建 File 对象代表的⽬录 ,如果必要 ,会创建中间⽬录 |
boolean | renameTo(Filedest) | 进⾏⽂件改名 ,也可以视为我们平 时的剪切、粘贴操作 |
boolean | canRead() | 判断⽤⼾是否对⽂件有可读权限 |
boolean | canWrite() | 判断⽤⼾是否对⽂件有可写权限 |
代码实例(一)
观察 get 系列的特点和差异
package io; import java.io.File; import java.io.IOException; public class Demo1 { public static void main(String[] args) throws IOException { File f = new File("./test.txt");//并不要求该⽂件真实存在 System.out.println(f.getParent());//返回 File 对象的⽗⽬录⽂件路径 System.out.println(f.getName());//返回 File 对象的纯⽂件名称 System.out.println(f.getPath());//返回 File 对象的⽂件路径 System.out.println(f.getAbsolutePath());//返回 File 对象的绝对路径 System.out.println(f.getCanonicalPath());//返回 File 对象的修饰过的绝对路径 } }
代码实例(二)
普通⽂件的创建、删除
package io; import java.io.File; import java.io.IOException; public class Demo2 { public static void main(String[] args) throws IOException { File f = new File("./test.txt"); //创建文件 f.createNewFile(); //判断 File 对象描述的⽂件是否真实存在 System.out.println(f.exists()); //判断 File 对象代表的⽂件是否是⼀个普通⽂件 System.out.println(f.isFile()); //判断 File 对象代表的⽂件是否是⼀个目录 System.out.println(f.isDirectory()); } }
代码实例(三)
观察 deleteOnExit 的现象
import java.io.File; import java.io.IOException; public class Demo3{ public static void main(String[] args) throws IOException { File file = new File("some-file.txt"); // 要求该⽂件不存在,才能看到 System.out.println(file.exists()); System.out.println(file.createNewFile()); System.out.println(file.exists()); file.deleteOnExit(); System.out.println(file.exists()); } }
程序运⾏结束后 ,⽂件还是被删除了
代码实例(四)
观察⽬录的创建
package io; import java.io.File; public class Demo4 { public static void main(String[] args) { File dir = new File("./testDir"); // dir.mkdirs(); 可以创建多级目录 dir.mkdir(); System.out.println(dir.isDirectory()); } }
代码实例(五)
观察⽂件重命名
package io; import java.io.File; //文件重命名 public class Demo5 { public static void main(String[] args) { File f1 = new File("./test.txt"); File f2 = new File("./test2.txt"); System.out.println(f1.renameTo(f2)); } }