zoukankan      html  css  js  c++  java
  • File IO(NIO.2):路径类 和 路径操作

    路径类

    Java SE 7版本中引入的Path类是java.nio.file包的主要入口点之一。如果您的应用程序使用文件I / O,您将需要了解此类的强大功能。 

    版本注意:如果您有使用java.io.File的JDK7之前的代码,则仍然可以使用File.toPath方法来利用Path类功能。有关详细信息,请参阅传统文件I / O代码。 

    顾名思义,Path类是文件系统中路径的编程表示形式。路径对象包含用于构建路径的文件名和目录列表,用于检查,定位和操作文件。 

    路径实例反映了底层平台。在Solaris OS中,路径使用Solaris语法(/ home / joe / foo),而在Microsoft Windows中,路径使用Windows语法(C: home joe foo)。路径与系统无关。您不能将Solaris与Solaris文件系统进行比较,并期望它与Windows文件系统中的路径相匹配,即使目录结构相同,并且两个实例都找到相同的相对文件。 

    与Path相对应的文件或目录可能不存在。您可以创建一个Path实例并以各种方式进行操作:您可以附加它,提取它,并将其与其他路径进行比较。在适当的时候,您可以使用Files类中的方法检查与Path对应的文件的存在,创建文件,打开它,删除它,更改其权限等。 

    下一页将详细介绍Path类。

    路径操作

    简介

    Path类包括可用于获取有关路径,路径访问元素,将路径转换为其他窗体或提取路径部分的信息的各种方法。还有一些方法可以匹配路径字符串和方法来删除路径中的冗余。这个课程解决了这些Path方法,有时被称为语法操作,因为它们在路径本身上操作,并且不访问文件系统。

    创建一个路径

    路径实例包含用于指定文件或目录位置的信息。在定义的时候,路径被提供有一系列一个或多个名称。可能包含根元素或文件名,但不是必需的。路径可能只包含一个目录或文件名。 您可以通过使用路径中的以下帮助类中的方法之一轻松创建一个Path对象(注意复数):
    Path p1 = Paths.get("/tmp/foo");
    Path p2 = Paths.get(args[0]);
    Path p3 = Paths.get(URI.create("file:///Users/joe/FileTest.java"));
    Paths.get方法是以下代码的缩写:
    Path p4 = FileSystems.getDefault().getPath("/users/sally");

    以下示例创建/u/joe/logs/foo.log,假设您的主目录是/ u / joe,或者C: joe logs foo.log(如果您在Windows上)。

    Path p5 = Paths.get(System.getProperty("user.home"),"logs", "foo.log");

    检索路径信息

    您可以将路径视为将这些名称元素作为序列存储。目录结构中的最高元素将位于索引0.目录结构中的最低元素将位于索引[n-1],其中n是路径中名称元素的数量。方法可用于使用这些索引检索单个元素或路径的子序列。 
    本课程中的示例使用以下目录结构。


    以下代码片段定义了一个Path实例,然后调用几个方法来获取有关该路径的信息:
    // None of these methods requires that the file corresponding
    // to the Path exists.
    // Microsoft Windows syntax
    Path path = Paths.get("C:\home\joe\foo");
    
    // Solaris syntax
    Path path = Paths.get("/home/joe/foo");
    
    System.out.format("toString: %s%n", path.toString());
    System.out.format("getFileName: %s%n", path.getFileName());
    System.out.format("getName(0): %s%n", path.getName(0));
    System.out.format("getNameCount: %d%n", path.getNameCount());
    System.out.format("subpath(0,2): %s%n", path.subpath(0,2));
    System.out.format("getParent: %s%n", path.getParent());
    System.out.format("getRoot: %s%n", path.getRoot());
    以下是Windows和Solaris操作系统的输出:

    上一个示例显示绝对路径的输出。在以下示例中,指定了相对路径:
    // Solaris syntax
    Path path = Paths.get("sally/bar");
    or
    // Microsoft Windows syntax
    Path path = Paths.get("sally\bar");
    以下是Windows和Solaris OS的输出:

    从路径中删除冗余数据

    许多文件系统使用“.” 表示当前目录的符号,“..”表示父目录。 您可能会遇到路径包含冗余目录信息的情况。 也许服务器配置为将其日志文件保存在“/ dir / logs /”中。 目录,并且您想要删除尾随的“/”。 
    以下示例都包括冗余:
    /home/./joe/foo
    /home/sally/../joe/foo
    normalize方法删除任何冗余元素,其中包括任何“.”或“目录/ ..”出现。以上两个例子都归结为/ home / joe / foo。 
    重要的是要注意,normalize在文件系统清理路径时不检查。这是一个纯粹的句法操作。在第二个例子中,如果sally是一个符号链接,则删除sally / ..可能会导致一个不再定位目标文件的路径。 要清理路径,同时确保结果找到正确的文件,可以使用toRealPath方法。该方法在下一节“转换路径”中进行了说明。

    转换路径

    您可以使用三种方法来转换路径。如果您需要将路径转换为可以从浏览器打开的字符串,则可以使用toUri。例如:
    Path p1 = Paths.get("/home/logfile");
    // Result is file:///home/logfile
    System.out.format("%s%n", p1.toUri());
    toAbsolutePath方法将路径转换为绝对路径。如果传入路径已经是绝对路径,则返回相同的路径对象。在处理用户输入的文件名时,toAbsolutePath方法非常有用。例如:
    public class FileTest {
        public static void main(String[] args) {
    
            if (args.length < 1) {
                System.out.println("usage: FileTest file");
                System.exit(-1);
            }
    
            // Converts the input string to a Path object.
            Path inputPath = Paths.get(args[0]);
    
            // Converts the input Path
            // to an absolute path.
            // Generally, this means prepending
            // the current working
            // directory.  If this example
            // were called like this:
            //     java FileTest foo
            // the getRoot and getParent methods
            // would return null
            // on the original "inputPath"
            // instance.  Invoking getRoot and
            // getParent on the "fullPath"
            // instance returns expected values.
            Path fullPath = inputPath.toAbsolutePath();
        }
    }
    toAbsolutePath方法转换用户输入并返回一个在查询时返回有用值的路径。该文件不需要存在,以使此方法正常工作。 
    toRealPath方法返回现有文件的真实路径。该方法可以执行多个操作: 
    1,如果true传递给此方法,并且文件系统支持符号链接,则此方法可以解析路径中的任何符号链接。 
    2,如果路径是相对的,则返回绝对路径。 
    3,如果路径包含任何冗余元素,它将返回一个删除这些元素的路径。
     如果文件不存在或无法访问,此方法将抛出异常。当您想处理这些情况时,您可以捕获异常。例如:
    try {
        Path fp = path.toRealPath();
    } catch (NoSuchFileException x) {
        System.err.format("%s: no such" + " file or directory%n", path);
        // Logic for case when file doesn't exist.
    } catch (IOException x) {
        System.err.format("%s%n", x);
        // Logic for other sort of file error.
    }

    联合两个路径

    你可以组合路径,通过使用resolve方法。 通过访问部分路径——不包括根节点,并且这个部分路径可以被添加到原始路径
    例如:思考以下代码:
    // Solaris
    Path p1 = Paths.get("/home/joe/foo");
    // Result is /home/joe/foo/bar
    System.out.format("%s%n", p1.resolve("bar"));
    或者
    // Microsoft Windows
    Path p1 = Paths.get("C:\home\joe\foo");
    // Result is C:homejoefooar
    System.out.format("%s%n", p1.resolve("bar"));
    将绝对路径传递给resolve方法返回传入路径:
    // Result is /home/joe
    Paths.get("foo").resolve("/home/joe");

    在两个路径之间创建一个新的路径

    一个很常见的需求是:当你在使用IO代码时,需要从一个文件系统的路径构建一个新的路径到另一个地方。你可以使用relativize方法,这个方法构建了从原来的路径和终点位置的路径中构建一个路径,这个新的路径对于原始路径来说,是相对的:
    例如:思考下面被定义为 Joe 和 Sally 的相对路径:
    Path p1 = Paths.get("joe");
    Path p2 = Paths.get("sally");
    对于其他信息而言,假设 Joe 和 Sally是兄妹,这意味着这个节点在树结构中有着同等的等级。 要想通过 Joe找到Sally,你可能需要首先找到这个父节点,然后找到Sally。
    // Result is ../sally
    Path p1_to_p2 = p1.relativize(p2);
    // Result is ../joe
    Path p2_to_p1 = p2.relativize(p1);
    再看一个略微复杂的例子:
    Path p1 = Paths.get("home");
    Path p3 = Paths.get("home/sally/bar");
    // Result is sally/bar
    Path p1_to_p3 = p1.relativize(p3);
    // Result is ../..
    Path p3_to_p1 = p3.relativize(p1);
    在这个例子中,两个路径共享了一个节点:home。 从home找到了bar,首先需要找到一个等级(home),然后再查找下一个等级找到Sally,最后再找到bar。从bar要找到home,需要向上查找两个等级。
    不能创建一个相对路径,如果这个路径包含根节点。如果这个路径包含根节点,只有系统有创建这个相对路径的能力。

    这个Copy 的递归例子,使用了relativize 和 resolve 方法。

    比较两个路径

    Path 类支持equals方法,这个方法让你可以检测两个路径是否一致。这个startsWith和endWith方法,使你可以检测任意一个以部分字符开始或结束的路径。这些方法使用起来都很简单,例如:
    Path path = ...;
    Path otherPath = ...;
    Path beginning = Paths.get("/home");
    Path ending = Paths.get("foo");
    
    if (path.equals(otherPath)) {
        // equality logic here
    } else if (path.startsWith(beginning)) {
        // path begins with "/home"
    } else if (path.endsWith(ending)) {
        // path ends with "foo"
    }

    Path类实现了Iterable接口,iterator方法返回一个对象,而这个对象让你可以遍历路径中的所有节点名称。第一个被返回的节点,是离目录树最近的根节点。下面的代码简单的遍历了一个路径,并打印每一个节点的名称:
    Path path = ...;
    for (Path name: path) {
        System.out.println(name);
    }
    Path类同样实现了comparable接口,你可以比较路径对象通过comparaTo方法,这个方法对于排序也同样有用。
    你也可以将一个Path对象放入一个collection ,查看集合 教程了解更多有用的功能。
    当你想确认两个路径对象是同一个文件时,你可以使用isSameFile方法,这个方法被描述在:检测两个路径是否存在于同一个文件

  • 相关阅读:
    华为全联接大会2019,共创智能新高度
    CTDC2019首席技术官领袖峰会,AI赋能 智享5G
    2019全球体验设计峰会:体验赋能商业,创造更好体验
    全球闪存峰会旨在深化技术创新,增进闪存产业链上下游
    PyCon 2019火热来袭,与大数据、人工智能等专家一起探讨Python语言
    PHPConChina 2019 PHP开发者大会将于8月在上海举办!
    2019腾讯Live开发者大会(TLC),引领技术新趋势
    2019 HTML5深度应用开发实践
    2019年5G物联网关键技术与应用培训,了解5G网络发展现状及进展
    2019第二届企业云服务大会 -- 企业智变,云化未来
  • 原文地址:https://www.cnblogs.com/hhx626/p/8320405.html
Copyright © 2011-2022 走看看