基于java Files类和Paths类的用法(详解)
Java7中文件IO发生了很大的变化,专门引入了很多新的类: import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; ......等等,来取代原来的基于java.io.File的文件IO操作方式. 1. Path就是取代File的 A Path represents a path that is hierarchical and composed of a sequence of directory and file name elements separated by a special separator or delimiter. Path用于来表示文件路径和文件。可以有多种方法来构造一个Path对象来表示一个文件路径,或者一个文件: 1)首先是final类Paths的两个static方法,如何从一个路径字符串来构造Path对象: Path path = Paths.get("C:/","Xmp"); Path path2 = Paths.get("C:/Xmp"); URI u = URI.create("file:///C:/Xmp/dd"); Path p = Paths.get(u); 2)FileSystems构造: Path path3 = FileSystems.getDefault().getPath("C:/","access.log"); 3)File和Path之间的转换,File和URI之间的转换: File file = new File("C:/my.ini"); Path p1 = file.toPath(); p1.toFile(); file.toURI(); 4)创建一个文件: Path target2 = Paths.get("C:mystuff.txt"); // Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rw-rw-rw-"); // FileAttribute<Set<PosixFilePermission>> attrs = PosixFilePermissions.asFileAttribute(perms); try { if(!Files.exists(target2)) Files.createFile(target2); } catch (IOException e) { e.printStackTrace(); } windows下不支持PosixFilePermission来指定rwx权限。 5)Files.newBufferedReader读取文件: try { // Charset.forName("GBK") BufferedReader reader = Files.newBufferedReader(Paths.get("C:my.ini"),StandardCharsets.UTF_8); String str = null; while((str = reader.readLine()) != null){ System.out.println(str); } } catch (IOException e) { e.printStackTrace(); } 可以看到使用 Files.newBufferedReader 远比原来的FileInputStream,然后BufferedReader包装,等操作简单的多了。 这里如果指定的字符编码不对,可能会抛出异常 MalformedInputException ,或者读取到了乱码: java.nio.charset.MalformedInputException: Input length = 1 at java.nio.charset.CoderResult.throwException(CoderResult.java:281) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) at java.io.BufferedReader.readLine(BufferedReader.java:389) at com.coin.Test.main(Test.java:79) 6)文件写操作: try { BufferedWriter writer = Files.newBufferedWriter(Paths.get("C:my2.ini"),StandardCharsets.UTF_8); writer.write("测试文件写操作"); writer.flush(); writer.close(); } catch (IOException e1) { e1.printStackTrace(); } 7)遍历一个文件夹: Path dir = Paths.get("D:webworkspace"); try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)){ for(Path e : stream){ System.out.println(e.getFileName()); } }catch(IOException e){ } try (Stream<Path> stream = Files.list(Paths.get("C:/"))){ Iterator<Path> ite = stream.iterator(); while(ite.hasNext()){ Path pp = ite.next(); System.out.println(pp.getFileName()); } } catch (IOException e) { e.printStackTrace(); } 上面是遍历单个目录,它不会遍历整个目录。遍历整个目录需要使用:Files.walkFileTree 8)遍历整个文件目录: public static void main(String[] args) throws IOException{ Path startingDir = Paths.get("C:apache-tomcat-8.0.21"); List<Path> result = new LinkedList<Path>(); Files.walkFileTree(startingDir,new FindJavaVisitor(result)); System.out.println("result.size()=" + result.size()); } private static class FindJavaVisitor extends SimpleFileVisitor<Path>{ private List<Path> result; public FindJavaVisitor(List<Path> result){ this.result = result; } @Override public FileVisitResult visitFile(Path file,BasicFileAttributes attrs){ if(file.toString().endsWith(".java")){ result.add(file.getFileName()); } return FileVisitResult.CONTINUE; } } 来一个实际例子: public static void main(String[] args) throws IOException { Path startingDir = Paths.get("F:uploadimages"); // F:uploadimages220141206 List<Path> result = new LinkedList<Path>(); Files.walkFileTree(startingDir,new FindJavaVisitor(result)); System.out.println("result.size()=" + result.size()); System.out.println("done."); } private static class FindJavaVisitor extends SimpleFileVisitor<Path>{ private List<Path> result; public FindJavaVisitor(List<Path> result){ this.result = result; } @Override public FileVisitResult visitFile(Path file,BasicFileAttributes attrs){ String filePath = file.toFile().getAbsolutePath(); if(filePath.matches(".*_[1|2]{1}.(?i)(jpg|jpeg|gif|bmp|png)")){ try { Files.deleteIfExists(file); } catch (IOException e) { e.printStackTrace(); } result.add(file.getFileName()); } return FileVisitResult.CONTINUE; } } 将目录下面所有符合条件的图片删除掉:filePath.matches(".*_[1|2]{1}.(?i)(jpg|jpeg|gif|bmp|png)") public static void main(String[] args) throws IOException { Path startingDir = Paths.get("F:222221uploadimages"); // F:222221uploadimages220141206 List<Path> result = new LinkedList<Path>(); Files.walkFileTree(startingDir,BasicFileAttributes attrs){ String filePath = file.toFile().getAbsolutePath(); int width = 224; int height = 300; StringUtils.substringBeforeLast(filePath,"."); String newPath = StringUtils.substringBeforeLast(filePath,".") + "_1." + StringUtils.substringAfterLast(filePath,"."); try { ImageUtil.zoomImage(filePath,newPath,width,height); } catch (IOException e) { e.printStackTrace(); return FileVisitResult.CONTINUE; } result.add(file.getFileName()); return FileVisitResult.CONTINUE; } } 为目录下的所有图片生成指定大小的缩略图。a.jpg 则生成 a_1.jpg 2. 强大的java.nio.file.Files 1)创建目录和文件: try { Files.createDirectories(Paths.get("C://TEST")); if(!Files.exists(Paths.get("C://TEST"))) Files.createFile(Paths.get("C://TEST/test.txt")); // Files.createDirectories(Paths.get("C://TEST/test2.txt")); } catch (IOException e) { e.printStackTrace(); } 注意创建目录和文件Files.createDirectories 和 Files.createFile不能混用,必须先有目录,才能在目录中创建文件。 2)文件复制: 从文件复制到文件:Files.copy(Path source,Path target,CopyOption options); 从输入流复制到文件:Files.copy(InputStream in,CopyOption options); 从文件复制到输出流:Files.copy(Path source,OutputStream out); try { Files.createDirectories(Paths.get("C://TEST")); if(!Files.exists(Paths.get("C://TEST"))) Files.createFile(Paths.get("C://TEST/test.txt")); // Files.createDirectories(Paths.get("C://TEST/test2.txt")); Files.copy(Paths.get("C://my.ini"),System.out); Files.copy(Paths.get("C://my.ini"),Paths.get("C://my2.ini"),StandardCopyOption.REPLACE_EXISTING); Files.copy(System.in,Paths.get("C://my3.ini"),StandardCopyOption.REPLACE_EXISTING); } catch (IOException e) { e.printStackTrace(); } 3)遍历一个目录和文件夹上面已经介绍了:Files.newDirectoryStream , Files.walkFileTree 4)读取文件属性: Path zip = Paths.get(uri); System.out.println(Files.getLastModifiedTime(zip)); System.out.println(Files.size(zip)); System.out.println(Files.isSymbolicLink(zip)); System.out.println(Files.isDirectory(zip)); System.out.println(Files.readAttributes(zip,"*")); 5)读取和设置文件权限: Path profile = Paths.get("/home/digdeep/.profile"); PosixFileAttributes attrs = Files.readAttributes(profile,PosixFileAttributes.class);// 读取文件的权限 Set<PosixFilePermission> posixPermissions = attrs.permissions(); posixPermissions.clear(); String owner = attrs.owner().getName(); String perms = PosixFilePermissions.toString(posixPermissions); System.out.format("%s %s%n",owner,perms); posixPermissions.add(PosixFilePermission.OWNER_READ); posixPermissions.add(PosixFilePermission.GROUP_READ); posixPermissions.add(PosixFilePermission.OTHERS_READ); posixPermissions.add(PosixFilePermission.OWNER_WRITE); Files.setPosixFilePermissions(profile,posixPermissions); // 设置文件的权限 Files类简直强大的一塌糊涂,几乎所有文件和目录的相关属性,操作都有想要的api来支持。这里懒得再继续介绍了,详细参见 jdk8 的文档。 一个实际例子: import java.io.BufferedReader; import java.io.BufferedWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class StringTools { public static void main(String[] args) { try { BufferedReader reader = Files.newBufferedReader(Paths.get("C:Members.sql"),StandardCharsets.UTF_8); BufferedWriter writer = Files.newBufferedWriter(Paths.get("C:Members3.txt"),StandardCharsets.UTF_8); String str = null; while ((str = reader.readLine()) != null) { if (str != null && str.indexOf(",CAST(0x") != -1 && str.indexOf("AS DateTime)") != -1) { String newStr = str.substring(0,str.indexOf(",CAST(0x")) + ")"; writer.write(newStr); writer.newLine(); } } writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); } } } 场景是,sql server导出数据时,会将 datatime 导成16进制的binary格式,形如:,CAST(0x0000A2A500FC2E4F AS DateTime)) 所以上面的程序是将最后一个 datatime 字段导出的,CAST(0x0000A2A500FC2E4F AS DateTime) 删除掉,生成新的不含有datetime字段值的sql 脚本。用来导入到mysql中。 做到半途,其实有更好的方法,使用sql yog可以很灵活的将sql server中的表以及数据导入到mysql中。使用sql server自带的导出数据的功能,反而不好处理。 以上这篇基于java Files类和Paths类的用法(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |