基于java Files类和Paths类的用法(详解)

作者:dmfrm 时间:2021-08-11 11:22:55 

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:\\upload\\images");  // F:\\upload\\images\\2\\20141206
   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:\\111111\\upload\\images");  // F:\111111\\upload\\images\\2\\20141206
   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();
     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, Path target, 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自带的导出数据的功能,反而不好处理。

来源:http://blog.csdn.net/u010889616/article/details/52694061

标签:java,path类,用法,files类
0
投稿

猜你喜欢

  • JAVA关键字及作用详解

    2022-05-03 03:50:14
  • Java实现简单的递归操作方法实例

    2021-11-01 14:37:32
  • java静态工具类注入service出现NullPointerException异常处理

    2021-11-28 09:59:11
  • Spring Boot启动过程完全解析(二)

    2022-06-17 14:40:59
  • Java实现带GUI的气泡诗词效果

    2022-09-12 18:04:48
  • spring boot 实现配置多个DispatcherServlet最简单方式

    2023-12-18 03:24:46
  • SpringBoot中使用Servlet三大组件的方法(Servlet、Filter、Listener)

    2021-07-19 18:41:43
  • 在Java中按值调用和按引用调用

    2021-12-26 20:09:21
  • Spring BeanFactory和FactoryBean区别解析

    2023-09-18 15:38:28
  • SpringBoot登录验证码实现过程详解

    2023-04-26 12:24:05
  • C#实现的xml操作类完整实例

    2023-02-12 03:52:16
  • Java Base64解码错误及解决方法

    2023-02-09 03:36:35
  • Java毕业设计实战之仿小米电子产品售卖商城系统的实现

    2022-09-29 10:19:47
  • Android转场效果实现示例浅析

    2023-09-21 12:10:17
  • java启动jar包将日志打印到文本的简单操作

    2021-12-05 10:42:21
  • Spring Cloud Gateway全局通用异常处理的实现

    2022-05-08 08:03:10
  • C# 时间戳转换实例

    2022-12-07 12:17:57
  • Spring Boot 读取静态资源文件的方法

    2023-08-25 02:53:07
  • java生成随机数的方法

    2023-12-12 12:49:51
  • java图形界面编程之模拟血压计

    2023-10-01 07:16:05
  • asp之家 软件编程 m.aspxhome.com