File类的使用
java.io.File 类: 文件和文件目录路径的抽象表示形式 ,与平台无关。File的一个对象,代表一个文件或文件目录。
File 能新建、删除、重命名文件和目录,但 File ==不能访问文件内容==本身。如果需要访问文件内容本身,则需要使用输入输出流 。
想要在 Java 程序中表示一个真实存在的文件或目录,那么必须有一个 File 对象 ,但是 Java 程序中的一个 File 对象,可能没有一个真实存在的文件或目录 。
File 对象可以作为参数传递给流的构造器。
// 创建File实例
public File(String pathname);// 以pathname 为路径创建 File 对象,可以是 绝对路径或者相对路径 ,如果pathname 是相对路径,则默认的当前路径在系统属性 user.dir 中存储。
// 方式1
public static final String separator; // File 类提供了一个常量,根据操作系统,动态的提供分隔符。
File file2 = new File(File(" d:"+ File.separator + " atguigu"+ separator + "info.txt");
// 方式2
public File(String parent,String child); //以parent 为父路径, child 为子路径创建 File 对象 。
// 方式3
public File(File parent,String child);//根据一个父File 对象和子文件路径创建 File 对象
常用函数:
public String getAbsolutePath(); // 获取绝对路径
public String getPath(); // 获取传入的路径
public String getName(); // 获取文件名称
public String getParent(); // 获取上层文件目录路径。 若无,返回null
public long length(); // 获取文件长度,即:字节数。 不能获取目录的长度。
public long lastModified(); // 获取最后一次的修改时间,毫秒值
public String[] list(); // 获取指定目录下的所有文件或者文件目录的名称数组,仅包含当前文件夹下的文件夹和文件
public File[] listFiles(); // 获取指定目录下的所有文件或者文件目录的File数组,仅包含当前文件夹下的文件夹和文件
public boolean renameTo(File dest); // 把文件重命名为指定的文件路径
// file1.renameTo(file2); 需要保证file1存在,file2不存在。若为True,move(非copy)的同时rename
public boolean isDirectory(); // 判断是否是文件目录
public boolean isFile(); // 判断是否是文件
public boolean exists(); // 判断是否存在
public boolean canRead(); // 判断是否可读
public boolean canWrite(); // 判断是否可写
public boolean isHidden(); // 判断是否隐藏
/*
文件确实存在硬盘中存在,创建File对象时,各个属性会显式赋值;文件不存在时,除了指定的目录和路劲之外,其余属性取成员变量的默认值。
*/
public boolean createNewFile(); // 创建文件。 若文件存在,则不创建,返回false
public boolean mkdir(); // 创建文件目录 。 如果此文件目录存在,就不创建了。
public boolean mkdirs(); // 创建文件目录 。 如果上层文件目录不存在一并创建
// 注意事项:如果你创建文件或者文件目录没有写盘符路径 那么默认在项目路径下。
public boolean delete(); // 删除文件或者文件夹,删除文件夹只能删空文件夹!
// 删除注意事项:Java中的删除不走回收站。要删除一个文件目录请注意该文件目录内不能包含文件或者文件目录
IO 流原理及流的分类
java.io 包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过 标准的方法 输入或输出数据。
- 按操作数据单位不同分为: 字节流 (8 bit),字符流 (16);
- 按数据流的流向不同分为: 输入流,输出流
- 按流的角色的不同分为: 节点流(直接从数据源或目的地读写数据);处理流(不直接连接到数据源或目的地,而是“连接” 在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。)
(抽象基类) | 字节流 | 字符流 |
---|---|---|
输入流 | InputStream | Reader |
输出流 | outputStram | Writer |
- Java 的 IO 流共涉及 40 多个类,实际上非常规则,都是从如下 4 个抽象基类派生的。
- 由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。
- FileOutputStream 从文件系统中的某个文件中获得输出字节 。 FileOutputStream用于 写出 非文本 数据之类的原始字节流。 要写出 字符流 需要使用 FileWriter
InputStream
int read(); // 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值 。 如果因为已经到达流末尾而没有可用的字节 则返回值 1
int read(byte[] b); // 从此输入流中将最多b.length 个字节的数据读入一个 byte 数组中 。 如果因为已经到达流末尾而没有可用的字节, 则返回值 1。 否则以整数形式返回实际读取的字节数 。
int read(byte[] b, int off,int len); // 将输入流中最多len 个数据字节读入 byte 数组 。 尝试读取 len 个字节, 但读取的字节也可能小于该值。 以整数形式返回实际读取的字节数。 如果因为流位于文件末尾而没有可用的字节, 则返回值 1 。
public void close() throws IOException; // 关闭此输入流并释放与该流关联的所有系统资源 。
Reader
int read(); // 读取单个字符。作为整数读取的字符, 范围在 0 到 65535 之间 0 x 00-0 xffff) 2 个字节的 Unicode 码, 如果已到达流的末尾, 则返回 1
int read(char[] cbuf); // 将字符读入数组。如果已到达流的末尾, 则返回 1 。 否则返回本次读取的字符数。
int read(char[] cbuf,int off,int len); // 将字符读入数组的某一部分。 存到数组 cbuf 中, 从 off 处开始存储, 最多读 len 个符 。 如果已到达流的末尾, 则返回 1。 否则返回本次读取的字符数。
public void close() throws IOException; // 关闭此输入流并释放与该流关联的所有系统资源 。
OutputStream
void write(int b); // 将指定的字节写入此输出流。 write 的常规协定是:向输出流写入一个字节。 要写入的字节是参数 b 的八个低位 。 b 的 24 个高位将被忽略。 即写入 0-255 范围 的。
void write(byte[] b); // 将b length 个字节从指定的 byte 数组写入此输出流 。 write(b) 的常规协定是:应该与调用 write(b, 0, b.length) 的效果完全相同。
void write(byte[] b,int off,int len); // 将指定byte数组中从偏移量 off 开始的 len 个字节写入此输出流 。
public void flush()throws IOException; // 刷新此输出流并强制写出所有缓冲的输出字节 调用此方法指示应将这些字节立即写入它们预期的目标。
public void close() throws IOException; // 关闭此输出流并释放与该流关联的所有系统资源。
Writer
void write(int c);// 写入单个字符。 要写入的字符包含在给定整数值的 16 个低位中, 16 高位被忽略。 即写入 0 到 65535 之间的 Unicode 码 。
void write(char[] cbuf); // 写入字符数组。
void write(char[] cbuf,int off,int len); // 写入字符数组的某一部分。 从 off 开始写入 len 个字符
void write(String str); // 写入字符串。
void write(String str,int off,int len); // 写入字符串的某一部分。
void flush(); // 刷新该流的缓冲则立即将它们写入预期目标 。
public void close() throws IOException; // 关闭此输出流并释放与该流关联的所有系统资源。
节点流或文件流
FileReader
read():返回读入的一个字符,如果达到文件末尾,返回-1
read(char[] b) 每次读取指定个数的字符,返回读取的字符数,如果达到文件末尾,返回-1。存在易错点:
FileReader fr = new FileReader(new File("Test.txt")); char[] cbuf = new char[5]; int len; while((len = fr.read(cbuf)) != -1){ //方式一: //错误的写法 //for(int i = 0;i < cbuf.length;i++){ //System.out.print(cbuf[i]); //} //正确的写法 for(int i = 0; i<len; i++){ System.out.print(cbuf[i]); } //方式二: //错误的写法,对应着方式一的错误的写法 //String str = new String(cbuf); //System.out.print(str); //正确的写法 String str = new String(cbuf,0,len); System.out.print(str);
资源关闭异常的处理:为保证资源一定可以执行关闭操作,需要使用try-catch-finally处理
读入的文件一定要存在,否则会报FileNotFoundException
FileWriter
FileWriter fw = new FileWriter(new File("Test.txt"));
/*File对应的硬盘中的文件如果不存在,在输出的过程中,会自动创建此文件。
File对应的硬盘中的文件如果存在:
如果流使用的构造器是:FileWriter(file,false) 或 FileWriter(file):对原有文件的覆盖
如果流使用的构造器是:FileWriter(file,true):不会对原有文件覆盖,而是在原有文件基础上追加内容*/
- 在写入一个文件时 ,如果使用构造器 FileOutputStream(file),则目录下有同名文件将被覆盖。
- 如果使用构造器 FileOutputStream(file,true),则目录下的同名文件不会被覆盖在文件内容末尾追加内容。
- 在读取文件时,必须保证该文件已存在 ,否则报异常 。
- 字节流操作字节,比如:.mp3 ,.avi ,.rmvb,.mp4 ,.jpg,.doc ,.ppt
- 字符流操作字符,只能操作普通文本文件 。 最常见的文本文件:.txt ,.java ,.c ,.cpp 等语言的源代码。尤其注意 .doc, excel, ppt 这些不是文本文件。
@Test
public void testFileReaderFileWriter() {
FileReader fr = null;
FileWriter fw = null;
try {
//1.创建File类的对象,指明读入和写出的文件
File srcFile = new File("hello.txt");
File destFile = new File("hello2.txt");
//不能使用字符流来处理图片等字节数据
// File srcFile = new File("爱情与友情.jpg");
// File destFile = new File("爱情与友情1.jpg");
//2.创建输入流和输出流的对象
fr = new FileReader(srcFile);
fw = new FileWriter(destFile);
//3.数据的读入和写出操作
char[] cbuf = new char[5];
int len;//记录每次读入到cbuf数组中的字符的个数
while((len = fr.read(cbuf)) != -1){
//每次写出len个字符
fw.write(cbuf,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
//4.关闭流资源
//方式一:
// try {
// if(fw != null)
// fw.close();
// } catch (IOException e) {
// e.printStackTrace();
// }finally{
// try {
// if(fr != null)
// fr.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
//方式二:
try {
if(fw != null)
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if(fr != null)
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
缓冲流
为了提高数据读写的速度 Java API 提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用 8192 个 字节 (8Kb) 的缓冲区 。
当读取数据时,数据按块读入缓冲区,其后的读操作则直接访问缓冲区。当使用 BufferedInputStream 读取字节文件时 BufferedInputStream 会一次性从文件中读取 8192 个 (8Kb),存在缓冲区中直到缓冲区装满了, 才重新从文件中读取下一个 8192 个字节数组 。向流中写入字节时不会直接写到文件,先写到缓冲区中,直到缓冲区写满BufferedOutputStream 才会把缓冲区中的数据一次性写到文件里 。==使用方法flush() 可以强制将缓冲区的内容全部写入输出流==。如果是带缓冲区的流对象的 close() 方法,不但会关闭,流 还会在关闭流之前刷新缓冲区,关闭后不能再写出。
缓冲 流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
- BufferedInputStream 和 BufferedOutputStream
- BufferedReader 和 BufferedWriter
//造流
//1 造节点流
FileInputStream fis = new FileInputStream((srcFile));
FileOutputStream fos = new FileOutputStream(destFile);
//2 造缓冲流
bis = new BufferedInputStream(fis);
bos = new BufferedOutputStream(fos);
//资源关闭
//要求:先关闭外层的流,再关闭内层的流
//说明:关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,我们可以省略.
//创建文件和相应的流
br = new BufferedReader(new FileReader(new File("dbcp.txt")));
bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));
//读写操作
//方式一:使用char[]数组
//char[] cbuf = new char[1024];
//int len;
//while((len = br.read(cbuf)) != -1){
//bw.write(cbuf,0,len);
// //bw.flush();
//}
//方式二:使用String
String data;
while((data = br.readLine()) != null){
//方法一:
//bw.write(data + "\n");//data中不包含换行符
//方法二:
bw.write(data);//data中不包含换行符
bw.newLine();//提供换行的操作
}
转换流
转换流提供了在字节流和字符流之间的转换
Java API 提供了两个转换流:
- InputStreamReader :将 InputStream 转换为 Reader
- OutputStreamWriter :将 Writer 转换为 OutputStream
字节流中的数据都是字符时,转成字符流操作更高效 。很多时候我们使用转换流来处理文件乱码问题。实现编码和解码的功能。
InputStreamReader
构造器:需要 和 InputStream “套接”。
- public InputStreamReader (InputStream in)
- public InputSreamReader (InputStream in, String charsetName)
OutputStreamWriter:
构造器:需要 和 OutputStream “套接”。
- public OutputStreamWriter (OutputStream out)
- public OutputSreamWriter (OutputStream out,String charsetName)
常见的编码表
- ASCII:美国标准信息交换码。用一个字节的 7 位可以表示。
- ISO8859-1:拉丁码表。欧洲码表,用一个字节的 8 位表示。
- GB2312:中国的中文编码表 。最多两个字节编码所有字符
- GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
- Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。
- UTF-8:变长的编码方式,可用 1-4个字节 来表示一个字符。
- GBK 等双字节编码方式,用最高位是 1 或 0 表示两个字节和一个字节 。
标准输入 、 输出流
- System.in 和 System.out 分别代表了系统标准的输入和输出设备
- 默认输入设备:键盘;输出设备:显示器
- System.in 的类型是 InputStream
- System.out 的类型是 PrintStream ,其是 OutputStream 的子类,FilterOutputStream 的子类
- 重定向:通过 System 类的 setIn,setOut 方法对默认设备进行改变,重新指定输入输出流
- public static void setIn (InputStream in)
- public static void setOut (PrintStream out)
System.out.println("请输入信息,退出输入 e 或 exit):");
//把标准输入流(键盘输入)这个字节流包装成字符流,再包装成缓冲流
BufferedReader br = new BufferedReader( new InputStreamReader(System.in));
String s = null;
try{
while ((s = br.readLine()) != null ) { // 读取用户输入的一行数据 ----> 阻塞程序
if(" e".equalsIngoreCase(s) ) || " exit".equalsIngoreCase(s)){
System.out.println("安全退出");
break;
}
//将读取到的整行字符串转成大写输出
System.out.println("---->:"+s.toUpperCase());
System.out.println("继续输入信息");
}
} catch (IOException e )
e.printStackTrace();
}
finally{
try{
if (br != null ){
br.close (); // 关闭过滤流时 会自动关闭它包装的底层节点流
}
}catch (IOException e){
e.printStackTrace();
}
}
打印流
实现将基本数据类型的数据格式转化为字符串输出。
打印流: PrintStream 和 PrintWriter
- 提供了一系列重载 的 print() 和 println() 方法 ,用于多种数据类型的输出
- PrintStream 和 PrintWriter 的输出不会抛出 IOException 异常
- PrintStream 和 PrintWriter 有自动 flush 功能
- PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类 。
- System.out 返回的是 PrintStream 的实例
@Test
public void test2() {
PrintStream ps = null;
try {
FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt")); // 创建打印输出流,设置为自动刷新模式(写入换行符或字节 '\n' 时都会刷新输出缓冲区)
ps = new PrintStream(fos, true);
if (ps != null) {// 把标准输出流(控制台输出)改成输出到文件
System.setOut(ps);
}
for (int i = 0; i <= 255; i++) { // 输出ASCII字符
System.out.print((char) i);
if (i % 50 == 0) { // 每50个数据一行
System.out.println(); // 换行
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (ps != null) {
ps.close();
}
}
}
数据流
为了方便地操作 Java 语言的基本数据类型和 String 的数据,可以使用数据流。
数据流有两个类:
- DataInputStream 和 DataOutputStream
- 分别“套接”在 InputStream 和 OutputStream 子类的流 上
- DataInputStream 中的方法
- boolean readBoolean
- byte readByte
- char readChar
- float readFloat
- double readDouble
- short readShort
- long readLong
- int readInt
- String readUTF ()
- void readFully (byte[] b)
- DataOutputStream 中的方法:将上述的方法的 read 改为相应的 write 即可。
- 读取数据的顺序需要和写入==顺序一致==!
对象流
ObjectInputStream 和 OjbectOutputSteam:用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把 Java 中的对象写入到数据源中,也能把对象从数据源中还原回来。
- 序列化: 用 ObjectOutputStream 类 保存 基本类型数据或对象的机制
- 反序列化: 用 ObjectInputStream 类 读取 基本类型数据或对象的机制
- ObjectOutputStream 和 ObjectInputStream 不能序列化 ==static== 和 ==transient== 修饰的成员变量
- 除了当前类需要实现Serializable接口之外,还必须保证其内部==所有属性==也必须是可序列化的。(默认情况下,==基本数据类型可序列化==)
- 对象序列化机制允许把内存中的 Java 对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络 节点 。 当 其它程序获取了这种二进制流,就可以恢复成原来的 Java 对象
- 序列化的好处在于可将任何实现了 Serializable 接口的对象转化为字节数据,使其在保存和传输时可被还原
- 序列化是 RMI (Remote Method Invoke 远程方法调用)过程的参数和返回值都必须实现的机制,而 RMI 是 JavaEE 的基础。因此序列化机制是JavaEE 平台的基础
- 如果需要让某个对象支持序列化机制,则必须 让对象所属的类及其属性是可序列化的,为了让 某个类是可序列化的,该类 必须实现如下两个接口 之一。否则,会抛出 NotSerializableException 异常
- Serializable
- Externalizable
凡是实现 Serializable 接口的类都有一个表示序列化版本标识符的静态变量:
- private static final long serialVersionUID;
- serialVersionUID 用来表明类的不同版本间的兼容性。 简言之,其目的是以序列化对象进行版本控制,有关各版本反序列化时是否兼容。
- 如果类没有显示定义这个静态常量 ,它的值是 Java 运行时环境根据类的内部细节自动生成的。 若类的实例变量做了修改 serialVersionUID 可能发生变化。 故建议,显式声明。
- 简单来说, Java 的序列化机制是通过在运行时判断类的 serialVersionUID 来验证版本一致性的。在进行反序列化时, JVM 会把传来的字节流中的serialVersionUID 与本地相应 实体类的 serialVersionUID 进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 (InvalidCastException)
谈谈你对java.io.Serializable 接口的理解,我们知道它用于序列化,是空方法接口,还有其它认识吗?
实现了 Serializable 接口的对象,可将它们转换成一系列字节,并可在以后完全恢复回原来的样子。 这一过程亦可通过网络进行。这意味着序列化机制能自动补偿操作系统间的差异。 换句话说,可以先在 Windows 机器上创建一个对象,对其序列化,然后通过网络发给一台 Unix 机器,然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示,也不必关心字节的顺序或者其他任何细节。
由于大部分作为参数的类如 String 、 Integer 等都实现了java.io.Serializable 的接口,也可以利用多态的性质,作为参数使接口更灵活。
随机存取文件流
- RandomAccessFile 声明在 java.io 包下,但直接继承于 java.lang.Object 类。 并
且它实现了 DataInput 、 DataOutput 这两个接口,也就意味着这个类既可以读也
可以写。 - RandomAccessFile 类支持 “随机访问” 的方式,程序可以直接跳到文件的任意地方来读、写文件
- 支持只访问文件的部分内容
- 可以向已存在的文件后==追加==内容
- RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。
RandomAccessFile 类对象可以自由移动记录指针:- long getFilePointer 获取文件记录指针的当前位置
- void seek(long pos) 将文件记录指针定位到 pos 位置
构造器
- public RandomAccessFile(File file , String mode)
- public RandomAccessFile(String name, String mode)
创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指
定 RandomAccessFile 的访问模式:
- r: 以只读方式打开
- rw:打开以便读取和写入;则会对原有文件内容进行覆盖。(默认情况下,从头覆盖)
- rwd: 打开以便读取和写入;同步文件内容的更新
- rws: 打开以便读取和写入; 同步文件内容和元数据的更新
- 如果模式为只读 r 。则不会创建文件,而是会去读取一个已经存在的文件,
如果读取的文件不存在则会出现异常。 如果模式为 rw 读写。如果文件不存在则会去创建文件,如果存在则不会创建。
我们可以用RandomAccessFile 这个类,来实现一个 多线程断点下载 的功能,用过下载工具的朋友们都知道,下载前都会建立 两个临时文件 ,一个是与被下载文件大小相同的空文件,另一个是记录文件指针的位置文件,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上一次的地方下载,从而实现断点下载或上传的功能,有兴趣的朋友们可以自己实现下。
NIO.2 中 Path 、 Paths 、Files 类的使用
Java API 中提供了两套 NIO 一套是针对标准输入输出 NIO 另一套就是网络编程 NIO 。
|----java.nio.channels.Channel
|----FileChannel: 处理本地文件
|----SocketChannel:TCP 网络编程的客户端的 Channel
|----ServerSocketChannel:TCP 网络编程的服务器端的 Channel
|----DatagramChannel:UDP 网络编程中发送端和接收端的 Channel
Path
早期 的 Java 只提供了一个 File 类来访问文件系统,但 File 类的功能比较有限,所提供的方法性能也不高。而且, 大多数方法在出错时仅返回失败,并不会提供异常信息。NIO. 2 为了弥补这种不足,引入了 Path 接口,代表一个平台无关的平台路径,描述了目录结构中文件的位置。 Path 可以看成是 File 类的升级版本,实际引用的资源也可以不存在。
Path 常用方法:
String toString(); 返回调用 Path 对象的字符串表示形式
boolean startsWith(String path); 判断是否以 path 路径开始
boolean endsWith(String path); 判断是否以 path 路径结束
boolean isAbsolute(); 判断是否是绝对路径
Path getParent(); 返回 Path 对象包含整个路径,不包含 Path 对象指定的文件路径
Path getRoot();返回调用 Path 对象的根路径
Path getFileName(); 返回与调用 Path 对象关联的文件名
int getNameCount(); 返回 Path 根目录后面元素的数量
Path getName(int idx); 返回指定索引位置 idx 的路径名称
Path toAbsolutePath(); 作为绝对路径返回调用 Path 对象
Path resolve(Path p); 合并两个路径,返回合并后的路径对应的 Path 对象
File toFile(); 将 Path 转化为 File 类的对象
Path与File类互换
File file = path.toFile();
Path path = file.toPath();
Paths、Files
同时, NIO.2 在 java.nio.file 包下还 提供了 Files 、 Paths 工具类, Files 包含
了大量静态的工具方法来操作文件; Paths 则包含了两个返回 Path 的静态工厂方法。
Paths 类提供的静态 get() 方法用来获取 Path 对象:
static Path get(String first, String … more); // 用于将多个字符串串连成路径
static Path get(URI uri); // 返回指定 uri 对应的 Path 路径
java.nio.file.Files 用于操作文件或目录的工具类。
Files 常用方法:
Path copy(Path src, Path dest, CopyOption … how); 文件的复制
Path createDirectory(Path path, FileAttribute<?> … attr); 创建一个目录
Path createFile(Path path, FileAttribute<?> … arr); 创建一个文件
void delete(Path path); 删除一个文件 目录,如果不存在,执行报错
void deleteIfExists(Path path); Path 对应的文件目录如果存在,执行删除
Path move(Path src, Path dest, CopyOption…how); 将 src 移动到 dest 位置
long size(Path path); 返回 path 指定文件的大小
boolean exists(Path path, LinkOption … opts); 判断文件是否存在
boolean isDirectory(Path path, LinkOption … opts); 判断是否是目录
boolean isRegularFile(Path path, LinkOption … opts); 判断是否是文件
boolean isHidden(Path path); 判断是否是隐藏文件
boolean isReadable(Path path); 判断文件是否可读
boolean isWritable(Path path); 判断文件是否可写
boolean notExists(Path path, LinkOption … opts); 判断文件是否不存在
SeekableByteChannel newByteChannel(Path path, OpenOption…how); 获取与指定文件的连
接, how 指定打开方式。
DirectoryStream<Path> newDirectoryStream(Path path); 打开 path 指定的目录
InputStream newInputStream(Path path, OpenOption…how); 获取 InputStream 对象
OutputStream newOutputStream(Path path, OpenOption…how); 获取 OutputStream 对象