Java7中的文件IO发生了很大的变化,引入了很多新的类,可以去看java.nio.file包。比如:1.7之前主要是通过File创建一个文件,然后将File作为输入参数,获取输入流等操作。而1.7开始,就采用了Path接口代替File类,且Files作为操作了,里面定义了很多非常有用的API。并且Paths主要是用来获取Path类。
之所以新增这些接口或者类,是因为java.io.File类有很多缺陷,它即使操作失败也不会抛出异常。Path更加高效。
一. Paths (工具类)
Paths类主要是用来生成Path对象的。
1. 类定义
public final class Paths
说明:这个类不可以被继承
2. 构造函数
private Paths() { },私有构造函数,不允许外界创建它的对象。
3.方法介绍
只有两个静态方法,一个是通过String类型的pathname来get到Path对象,另外一个是根据URI来get到Path对象。
(1)根据string类型的pathname
1 public static Path get(String first, String... more) { 2 return FileSystems.getDefault().getPath(first, more); 3 }
说明:第二个参数是个变参。举例
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.nio.file.Path; 5 import java.nio.file.Paths; 6 7 public class Test { 8 public static void main(String args[]) throws IOException { 9 String dirname = "C:\Users\hermioner\Desktop\test"; 10 // Path path=Paths.get(dirname); 11 Path path=Paths.get("C:\Users\hermioner", "Desktop","test");//效果同get(dirname) 12 System.out.println(path.getNameCount());//获取test路径下的文件和目录的个数和 13 14 15 } 16 17 18 }
(2)根据URI类型
1 public static Path get(URI uri)
举例使用:
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.net.URI; 5 import java.nio.file.Path; 6 import java.nio.file.Paths; 7 8 public class Test { 9 public static void main(String args[]) throws IOException { 10 String dirname = "C:/Users/hermioner/Desktop/test"; 11 Path path2=Paths.get(URI.create("file:///Users/hermioner/Desktop/test")); 12 System.out.println(path2.getNameCount());//获取test路径下的文件和目录的个数和 13 } 14 }
二. Path接口(替代File)
Path是1.7作为File的替代类的,但是也不是完全替代,它们可以结合使用。有多种方法可以用来生成Path对象,比如Paths中的静态方法get,还有就是可以通过FileSystems(java.nio.file)这个final类来间接生成Path对象。
1. FileSystems类介绍
这是一个文件系统类,通过这个类可以来访问文件系统。路径属于文件系统,实际上它是存储和组织媒体文件的格式,通常在一块或多块硬盘设备上,以便于非常容易地检索。
FileSystems类中方法主要是用来返回FileSystem(java.nio.file)对象。通过FIleSystem类中的getPath方法可以返回Path对象。
(1)public static FileSystem getDefault()
说明:这个静态方法会返回一个默认的FileSystem给JVM,通常这是操作系统默认的文件系统。
(2) public static FileSystem getFileSystem(URI uri)
说明:根据URI返回FIleSystem.
2. 采用FileSystems来生成Path对象
1 public class Test { 2 public static void main(String args[]) throws IOException { 3 String dirname = "C:/Users/hermioner/Desktop/test"; 4 Path path=FileSystems.getDefault().getPath("C:/a","test"); 5 System.out.println(path.isAbsolute()); 6 } 7 }
说明:上面打印结果为true。但是实际上并不存在a这个路径。(如果将C:/去掉或者C:去掉,就会打印false,因为不是绝对路径)。同时也可以说明,一个 Path 类 是一个路径在文件系统中的程序表示。Path基本上就是一个文件路径的字符串,实际的引用的资源可以不存在。
3. Path接口中的对象的使用
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.nio.file.FileSystems; 5 import java.nio.file.Path; 6 7 public class Test { 8 public static void main(String args[]) throws IOException { 9 String dirname = "C:/Users/hermioner/Desktop/test"; 10 Path path=FileSystems.getDefault().getPath("C:/a","test"); 11 System.out.println(path.getFileName()); 12 System.out.println(path.getNameCount()); 13 System.out.println(path.getName(1)); 14 System.out.println(path.getName(0)); 15 System.out.println(path.getParent()); 16 System.out.println(path.getRoot()); 17 System.out.println(path.subpath(0, 1)); 18 } 19 } 20 21 test 22 2 23 test 24 a 25 C:a 26 C: 27 a
说明:根据上面例子可以看出各个方法的作用:
(1)getFileName()
得到返回的文件或者目录的名字
(2)getNameCount()
得到路径层级的个数
(3)getName(int index)
得到索引为index处的文件的名字
(4)getParent()
得到当前文件路径的父路径
(5)getRoot()
得到当前文件路径的根路径
(6)getsubpath(int beginIndex,int endIndex)
得到子路径.。前闭后开。
(7)to系列方法
1 package com.test.a; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.net.URI; 6 import java.nio.file.FileSystems; 7 import java.nio.file.LinkOption; 8 import java.nio.file.Path; 9 10 public class Test { 11 public static void main(String args[]) throws IOException { 12 String dirname = "C:/Users/hermioner/Desktop/test"; 13 Path path=FileSystems.getDefault().getPath("C:/a","test"); 14 Path path2=FileSystems.getDefault().getPath("C:/Users/hermioner/Desktop", "test"); 15 Path path3=path.toAbsolutePath(); 16 System.out.println(path3); //实际调用的是path3的tostring方法 17 Path path4=path2.toRealPath(LinkOption.NOFOLLOW_LINKS);//reapath,必须保证Path2代表的路径是真是存在的,用a/test就不行,因为没有 18 System.out.println(path4); 19 URI uri=path.toUri(); 20 System.out.println(uri); 21 File file=path.toFile(); 22 System.out.println(file); 23 System.out.println(file.exists());//false 24 } 25 } 26 27 C:a est 28 C:UsershermionerDesktopTest 29 file:///C:/a/test 30 C:a est 31 false
说明:1)URI toUri(); Path和URI之间的转换
2)Path toAbsolutePath();
3)Path toRealPath(LinkOption... options) throws IOException; //要求path对象必须真是存在,否则就会有异常
4)File toFile(); Path和File之间的转换
5)String toString(); Path转换成字符串形式
(8)resove(String)或者resove(path)
1 public class Test { 2 public static void main(String args[]) { 3 String dirname = "C:/Users/hermioner/Desktop/test"; 4 Path path=FileSystems.getDefault().getPath("C:/a","test"); 5 Path path2=FileSystems.getDefault().getPath("C:/Users/hermioner/Desktop", "test"); 6 7 Path basePath=Paths.get("C:/Users/hermioner/Desktop"); 8 Path subPath=basePath.resolve("test"); 9 System.out.println(subPath);//打印:C:UsershermionerDesktop est 10 11 } 12 }
说明:这个方法用于合并两个路径成一个路径。它允许你先定义一个固定的根目录然后再附上局部的路径
(9)resolveSibling(String)或者resolveSilbing(path)
1 public class Test { 2 public static void main(String args[]) throws IOException { 3 Path path=FileSystems.getDefault().getPath("C:/a","test"); 4 Path path2=path.resolveSibling("b"); 5 System.out.println(path2); //打印C:a 6 } 7 }
说明:替换路径:它会根据给定的路径去替换当前的路径。
(10)还提供了判断两个文件是否是一个的方法。
三. Files(工具类)
1. Files.copy(source,destination)
1 public class Test { 2 public static void main(String args[]) throws IOException { 3 Path source=Paths.get("C:\Users\hermioner\Desktop\A.txt"); 4 Path dest=Paths.get("C:\Users\hermioner\Desktop\G.txt"); 5 File file=new File("C:\Users\hermioner\Desktop\D.txt"); 6 file.createNewFile(); 7 Files.copy(source, new FileOutputStream(file));//将A中的内容写入到了D中去了。必须保证A和D都是存在的。多次运行,内容不会因为运行次数的增加而增加 8 Files.copy(source, dest);//必须保证F.txt是不存在的,否则有异常,复制的同时,它会自动创建des这个新的路径文件。 9 } 10 }
说明:Files提供了4个复制文件的方法。可以将一个地方的内容复制到另外一个地方去。四个方法都是从source到destination。源可以为path类型或者inputstream类型;des可以为path类型或者outputstream. 排列组合参数。
2. Files.wirte(dest,dataList或者byte[])
1 public class Test { 2 public static void main(String args[]) throws IOException { 3 // 写入内容到文件 4 Path dest=Paths.get("C:\Users\hermioner\Desktop\A.txt"); 5 ArrayList<String> as = new ArrayList<>(); 6 as.add("e"); 7 as.add("f"); 8 as.add("g"); 9 Files.write(dest, as);//不会追加,当as中的内容修改时,不会保存之前的值,只保留新的值。 10 11 } 12 }
说明:假设A.txt文件中什么内容都没有,现在通过Files.wirte方法写入集合as中的内容。这样A.txt文件中的内容就编程e,f,g。
3. Files.getFileStore(Path)
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.nio.file.FileStore; 5 import java.nio.file.Files; 6 import java.nio.file.Path; 7 import java.nio.file.Paths; 8 import java.util.ArrayList; 9 10 public class Test { 11 public static void main(String args[]) throws IOException { 12 // 获取Paths对象对应的文件路径的文件储存 13 FileStore f = Files.getFileStore(Paths.get("C:")); 14 System.out.println("C盘的总大小" + f.getTotalSpace()); 15 System.out.println("C盘的可用大小" + f.getUsableSpace()); 16 System.out.println("C盘的未分配空间" + f.getUnallocatedSpace()); 17 18 } 19 } 20 21 C盘的总大小254600593408 22 C盘的可用大小104576507904 23 C盘的未分配空间104576507904
4. Files中的boolean系列方法
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.nio.file.Files; 5 import java.nio.file.Path; 6 import java.nio.file.Paths; 7 import java.util.ArrayList; 8 9 public class Test { 10 public static void main(String args[]) throws IOException { 11 // 写入内容到文件 12 Path dest = Paths.get("C:\Users\hermioner\Desktop\A.txt"); 13 ArrayList<String> dataList = new ArrayList<>(); 14 dataList.add("e"); 15 dataList.add("f"); 16 dataList.add("g"); 17 Files.write(dest, dataList);// 不会追加,当as中的内容修改时,不会保存之前的值,只保留新的值。 18 19 // 返回值为boolean的操作方法样例 20 System.out.println(Files.isHidden(dest));// 文件是否隐藏 21 System.out.println(Files.isExecutable(dest));// 文件是否可执行 22 System.out.println(Files.isWritable(dest));// 文件是否可写 23 24 25 26 } 27 } 28 29 30 false 31 true 32 true
5. Files.createDirectories(Path) & Files.createFile(Path)
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.nio.file.Files; 5 import java.nio.file.Paths; 6 7 public class Test { 8 public static void main(String args[]) throws IOException { 9 Files.createDirectories(Paths.get("C:\Users\hermioner\Desktop\MyTest")); 10 if (Files.exists(Paths.get("C:\Users\hermioner\Desktop\MyTest"))) { 11 Files.createFile(Paths.get("C:\Users\hermioner\Desktop\MyTest\test.txt")); 12 } else { 13 Files.createDirectories(Paths.get("C:\Users\hermioner\Desktop\MyTest")); 14 } 15 } 16 }
说明:就会自动创建目录和文件。创建目录用createDirectories,创建文件用createFile
6. 读取文件属性
1 package com.test.a; 2 3 import java.io.IOException; 4 import java.nio.file.Files; 5 import java.nio.file.Path; 6 import java.nio.file.Paths; 7 8 public class Test { 9 public static void main(String args[]) throws IOException { 10 Path path=Paths.get("C:\Users\hermioner\Desktop\Test"); 11 System.out.println(Files.getLastModifiedTime(path)); 12 System.out.println(Files.size(path)); 13 System.out.println(Files.isSymbolicLink(path)); 14 System.out.println(Files.isDirectory(path)); 15 System.out.println(Files.readAttributes(path, "*")); 16 } 17 } 18 19 20 2018-10-09T12:33:50.294696Z 21 4096 22 false 23 true 24 {lastAccessTime=2018-10-09T12:33:50.294696Z, lastModifiedTime=2018-10-09T12:33:50.294696Z, size=4096, creationTime=2018-10-09T02:35:50.859106Z, isSymbolicLink=false, isRegularFile=false, fileKey=null, isOther=false, isDirectory=true}
7. Files还有好多方法,比如读数据,设置文件权限等等操作。暂时没有研究。
总结:新添加了这么多,功能特别多。总结来说Paths和FileSystems用来生成Path对象的;而Path是用来替代File的,理解成代表路径的对象;Files工具类就用来操作文件或者目录的。