分享

便携的文件操作-Files

 印度阿三17 2020-03-04

便携的文件操作-Files

分隔符

  • 在Windows系统中使用反斜杠 ‘’ 或者斜杠 '/'来当作路径的分隔符,但是使用反斜杠需要注意: 单个反斜杠代表转义字符,所以在使用反斜杠充当路径的分隔符时需要成对出现

    File file1 = new File("E:\\aaa\\1.java");
    File file2 = new File("E:/aaa/1.java");
    
  • 在Linux,Unix,macOS中,使用斜杠 ‘/’ 来作为路径的分隔符

  • 可以使用File类提供的File.separator,程序会根据当前的系统匹配系统对应的分隔符

    File file3 = new File("D:"   File.separator   "aaaa"   File.separator   "1.java");
    

Path

概述

Path表示的是一个目录名序列,其后还可以跟着一个文件名。路径中的第一个部分可以是根目录,例如/C:\,以根目录开始的路径是绝对路径,否则是相对路径。举个例子:

Path path = Paths.get("/home", "path", "demo");
path = /home/path/demo

Path path1 = Paths.get("home", "path", "demo");
path1 = home/path/demo
Path API
//组合路径。如果other是绝对路径,那么就返回other;否则,返回通过连接this和other获得的路径
Path resolve(String other);
Path resolve(Path other);

//组合路径。如果other是绝对路径,那么就返回other;否则,返回通过连接this的父路径和other获得的路径
Path resolveSibling(String other);
Path resolveSibling(Path other);
//返回相对于other的相对路径
Path relativize(other);
//移除.和..等冗余的路径元素
Path normalize();
//返回绝对路径
Path toAbsolutePath();
//返回父路径,如果没有则返回null
Path getParent();
//返回路径的最后一个路径部件
Path getFileName();
//返回文件的跟路径
Path getRoot();
//从该路径中创建以个File对象
Path toFile();

Files

概述

Files工具类可以使得普通文件操作变得快捷。例如:

//读取文件所有内容
byte[] bytes = Files.readAllBytes(path);
//按行读入
List<String> lines = Files.readAllLines(path);
List<String> lines = Files.readAllLines(path, StandardCharsets.UTF_8);
//写出文件
Path write = Files.write(path, bytes);
Path write = Files.write(path, lines);

这些简便的方法适用于处理中等长度的文件,如果要处理的文件长度比较大,或者是二进制文件,那么还是应该使用输入/输出流或读入器/写出器:

InputStream in = Files.newInputStream(path);
OutputStream out = Files.newOutputStream(path);
BufferedReader in = Files.newBufferedReader(path);
BufferedWriter out = Files.newBufferedWriter(path);
创建文件和目录
//创建目录
Path directory = Files.createDirectory(path);
//递归创建目录
Path directory1 = Files.createDirectories(other);
//创建文件
Path file = Files.createFile(filePath);

//创建临时文件|目录
Path tempFile = Files.createTempFile(path, "demoTemp", ".text");
//新建的文件为:path/demoTemp1755677485909684463.text
Path tempFile1 = Files.createTempFile("demoTemp", ".text");
//新建文件为:/var/.../demoTemp7347118361156223079.text
Path tempFile2 = Files.createTempFile(null, ".text");
//新建文件为:/var/.../6300881984327212300.text
Path tempDirectory = Files.createTempDirectory(path, "demoTemp");
//新建的目录为:path/demoTemp201107870961044007
Path tempDirectory1 = Files.createTempDirectory("demoTemp");
//新建的目录为:/var/.../demoTemp4584110971885510312
复制、移动和删除文件
/**
 * fromPath:/path/from/demo.text
 * toPath:/path/to/demo.text
 */
//复制文件
Path copy = Files.copy(fromPath, toPath);
//将输入流存储到硬盘上
long copy2 = Files.copy(inputStream, toPath);
//将Path复制到输出流
long copy1 = Files.copy(fromPath, outputStream);
//移动文件
Path move = Files.move(fromPath, toPath);
//删除文件,如果文件不存在会抛异常
Files.delete(toPath);
//删除文件或移除空目录
boolean exists = Files.deleteIfExists(toPath);

复制文件时如果目标路径已经存在,那么复制或移动将失败。如果想要覆盖已有的目标路径,可以使用REPLACE_EXISTING选项。如果要复制文件所有属性,可以使用ATTRIBUTES选项。可以使用ATOMIC_MOVE选项来保证移动的原子性

Path move = Files.move(fromPath, toPath, StandardCopyOption.ATOMIC_MOVE);
访问目录中的项

静态的Files.list方法会返回一个可以读取目录中各个项的Stream对象。目录是被惰性读取的,这使得处理具有大量项目的目录可以更高效。

使用Files.walk方法可以递归方式获取所有子目录。使用walk方法删除目录树比较困难,因为需要在删除父目录之前先删除子目录

因为读取目录涉及需要关闭系统资源,所以应该使用try块:

try(Stream<Path> entries = Files.list(path)){
	...
}

示例:将一个目录复制到另外一个目录

Path target = Paths.get("");
Files.walk(path).forEach(p -> {
    try {
        Path q = target.resolve(p);
        if (Files.isDirectory(p)) {
            Files.createDirectory(q);
        } else {
            Files.copy(p, q);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
});
使用目录流

使用目录流删除目录树

Path root = Paths.get("");
Files.walkFileTree(root, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Files.delete(file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
        if (e != null) {
            throw e;
        }
        Files.delete(dir);
        return FileVisitResult.CONTINUE;
    }
});

附录

Files API
//创建文件或目录
static Path createDirectory(Path dir, FileAttribute<?>... attrs)
static Path createDirectories(Path dir, FileAttribute<?>... attrs)
static Path createFile(Path path, FileAttribute<?>... attrs)
//在合适临时文件的位置或给定父目录创建临时文件或目录,返回创建文件或目录的路径
static Path createTempFile(Path dir, String prefix, String suffix, FileAttribute<?>... attrs)
static Path createTempFile(String prefix, String suffix, FileAttribute<?>... attrs)
static Path createTempDirectory(Path dir, String prefix, FileAttribute<?>... attrs)
static Path createTempDirectory(String prefix, FileAttribute<?>... attrs)
//将from复制或移动到制定位置,并返回to
static Path copy(Path source, Path target, CopyOption... options);
static Path move(Path source, Path target, CopyOption... options);
//从输入流复制到文件或从从文件复制到输出流
static long copy(Path source, OutputStream out);
static long copy(InputStream in, Path target, CopyOption... options);
//删除文件或空目录
static void delete(Path path);
static boolean deleteIfExists(Path path);
//第一个当文件或目录不存在时会抛异常,而第二个会直接返回false

//获取文件信息
static boolean exists(Path path, LinkOption... options);
static boolean isHidden(Path path, LinkOption... options);
static boolean isReadable(Path path);
static boolean isWritable(Path path);
static boolean isExecutable(Path path);
static boolean isRegularFile(Path path, LinkOption... options);
static boolean isDirectory(Path path, LinkOption... options);
static boolean isSymbolicLink(Path path);
//获取文件的字节数
static long size(Path path);
//读取类型为A的文件属性
static <A extends BasicFileAttributes> A readAttributes(Path path,Class<A> type,LinkOption... options);

//获取目录中的文件或目录
static DirectoryStream<Path> newDirectoryStream(Path dir);
static DirectoryStream<Path> newDirectoryStream(Path dir, String glob);
//遍历所有子孙
static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
用于文件操作的标准选项
  • StandardOpenOption

    选项 描述
    READ 用于读取而打开
    WRITE 用于写入而打开
    APPEND 写入时在文件末尾追加
    TRUNCATE_EXISTING 写入时移除文件已有内容
    CREATE 自动在文件不存在的情况下创建文件
    CREATE_NEW 创建文件时如果文件存在则创建失败
    DELETE_ON_CLOSE 当文件被关闭时尽“可能”的删除该文件
    SPARSE 给文件系统一个提示,表示文件是稀疏的
    SYNC 对数据和元数据的每次更新都必须同步的写入到存储设备中
    DSYNC 对文件数据每次更新都必须同步的写入到存储设备中
  • StandardCopyOption

    选项 描述
    REPLACE_EXISTING 如果目标已存在,则替换他
    COPY_ATTRIBUTES 复制文件的所有属性
    ATOMIC_MOVE 原子性的移动文件
  • LinkOption

    选项 描述
    NOFOLLOW_LINKS 不要跟踪符号链接
  • FileVisitOption

    选项 描述
    FOLLOW_LINKS 跟踪符号链接
Glob模式ß
模式 描述 示例
* 匹配路径组成部分中0个或多个字符(不含子目录) *.java
** 匹配跨目录边界的0个或多个字符(含子目录) **.java
匹配一个字符 demo?.java
[…] 匹配一个字符集([0-9]、[A-F]、[!0-9]) demo[0-9].java
{…} 匹配由逗号隔开的多个可选项之一 *.{java, class}
\ 转译上述任意模式中的字符以及\字符
来源:https://www./content-4-648851.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多