Java无法获取当前目录中存在的文件的路径

时间:2011-08-22 21:19:20

标签: java filesystems

如果文件存在于运行Java应用程序的同一目录中,并且我为该文件创建了一个File对象,则该文件路径的Java File方法也包含文件名。代码和输出如下。

如果这是JDK版本中的一个错误我正在使用某人肯定会看到它。

为什么File.getAbsolutePath()和File.getCanonicalPath()包含文件名? Javadocs表示应该返回目录名。

import java.io.File;
import java.io.IOException;


public class DirectoryFromFile {

    private void getDirectoryOfFile(String fileName) throws IOException{

        File f = new File(fileName );

        System.out.println("exists(): " + f.exists());
        System.out.println("getPath(): " + f.getPath());
        System.out.println("getAbsolutePath(): " + f.getAbsolutePath());
        System.out.println("getParent(): " + f.getParent() );
        System.out.println("getCanonicalPath(): " + f.getCanonicalPath() );
        System.out.println("getAbsoluteFile().getCanonicalPath(): " + f.getAbsoluteFile().getCanonicalPath() );
        String dirname = f.getCanonicalPath();
        System.out.println("dirname: " + dirname);
        File dir = new File(dirname);
        System.out.println("dir: " + dir.getAbsolutePath());

        if (dirname.endsWith(fileName))
            dirname = dirname.substring(0, dirname.length() - fileName.length());
        System.out.println("dirname: " + dirname);
        File dir2 = new File(dirname);
        System.out.println("dir2: " + dir2.getAbsolutePath());
    }

    public static void main(String[] args) {

        DirectoryFromFile dff = new DirectoryFromFile();
        try {
            dff.getDirectoryOfFile("test.txt");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

这里是输出:

exists(): true
getPath(): test.txt
getAbsolutePath(): C:\dean\src\java\directorytest\directory.from.file\test.txt
getParent(): null
getCanonicalPath(): C:\dean\src\java\directorytest\directory.from.file\test.txt
getAbsoluteFile().getCanonicalPath(): C:\dean\src\java\directorytest\directory.from.file\test.txt
dirname: C:\dean\src\java\directorytest\directory.from.file\test.txt
dir: C:\dean\src\java\directorytest\directory.from.file\test.txt
dirname: C:\dean\src\java\directorytest\directory.from.file\
dir2: C:\dean\src\java\directorytest\directory.from.file

到目前为止,我发现在这种情况下获取目录的唯一方法是手动解析文件名。

在这种情况下,File类是否有办法获取目录名称(创建当前目录中存在的文件而不指定目录)?

5 个答案:

答案 0 :(得分:10)

  

为什么File.getAbsolutePath()和File.getCanonicalPath()包含   文件名? Javadocs表明目录名称应该是   返回。

不,他们没有。如果你想指出你认为他们为什么这样做,有人可能会在你的推理中发现错误。此外,如果您在给定特定输入的情况下准确指定了您希望看到的输出,我们也可以帮助您。您的问题标题似乎也很奇怪,因为您的问题似乎是 返回文件的完整路径。

编辑:我想我理解你的混乱的根源。 File表示与平台无关的文件系统路径。它可以是文件或目录的路径。它也总是表示相同的路径,但不一定是相同的绝对路径。这是一个非常精细的区别,但非常重要。表示相对路径的File对象始终是相对的。给定表示相对路径的File,您可以使用getAbsolutePath()获取当前对应的绝对路径。但是,这并没有改变File表示相对路径的事实。在同一File对象上进一步调用getAbsolutePath()可能会返回不同的值。例如,考虑一下:

// A relative file
File foo = new File("foo.txt");
// Resolve relative file against CWD
System.out.println(foo.getAbsolutePath());
    // Output: D:\dev\projects\testbed\foo.txt
System.setProperty("user.dir", "C:\\somewhere");
// Resolve relative file against new CWD
System.out.println(foo.getAbsolutePath());
    // Output: C:\somewhere\foo.txt
// Get an absolute file
File absoluteFoo = foo.getAbsoluteFile();
// Show absolute path
System.out.println(absoluteFoo.getAbsolutePath());
    // Output: C:\somewhere\foo.txt
System.setProperty("user.dir", "D:\\somewhere-else");
// An absolute path doesn't change when the CWD changes
System.out.println(absoluteFoo.getAbsolutePath());
    // Output: C:\somewhere\foo.txt

现在应该清楚,File表示的路径只是:路径。此外,路径可以由零个或多个部分组成,并且在任何File上调用getParent()会返回该文件的路径,并删除最后一个路径元素,除非没有要删除的“最后路径元素”。因此new File("foo").getParent()的预期结果是null,因为相对路径“foo”没有父级。

从上面的示例和解释中,您应该能够看到在创建相对路径File对象时获取包含目录的方法是

String absoluteParentDirPath = someRelativeFile.getAbsoluteFile().getParent();

需要注意的是,“绝对路径”取决于您当时的环境。

附加说明:由于File是Serializable,您可以将相对路径文件写入磁盘或通过网络发送。该文件在另一个JVM中反序列化时仍将表示相对路径,并将针对该JVM的当前工作目录进行解析。

答案 1 :(得分:1)

预期会有这种行为。 documentation未提及未包含文件名。

也许您对getAbsolutePath()getAbsoluteFile()之间的区别感到困惑。后者返回File个实例。

答案 2 :(得分:1)

我不确定为什么你认为Javadoc说它返回了目录名。

这是Javadoc -

文件和目录路径名的抽象表示。

用户界面和操作系统使用依赖于系统的路径名字符串来命名文件和目录。此类提供了一个抽象的,与系统无关的分层路径名视图。抽象路径名有两个组成部分:

  1. 可选的系统相关前缀字符串,例如磁盘驱动器说明符,UNIX根目录为“/”,Microsoft Windows UNC路径名为“\\”,
  2. 零个或多个字符串名称的序列。
  3. 抽象路径名中的第一个名称可以是目录名,如果是Microsoft Windows UNC路径名,则可以是主机名。 抽象路径名中的每个后续名称表示一个目录;姓氏可以表示目录或文件。空的抽象路径名没有前缀和空名称序列。

    http://download.oracle.com/javase/6/docs/api/java/io/File.html#getAbsolutePath%28%29

    返回此抽象路径名的绝对路径名字符串。

答案 3 :(得分:1)

除了getAbsolutePathgetCanonicalPath的现有答案之外,请注意,File.getParent()并不意味着“父目录”它只是指父文件对象用于创建文件。

例如,如果可以这样创建文件对象:

File dir = new File("/path/to/a/directory");
File f1 = new File(dir, "x.txt");
File f2 = new File(dir, "../another/y.txt");
File f3 = new File("z.txt");

f1会引用/path/to/a/directory/x.txt,它的父母是dir/path/to/a/directory

f2会引用/path/to/a/directory/../another/y.txt,它的规范路径为/path/to/a/another/y.txt,但它的父级仍然是dir的引用(/path/to/a/directory

f3将引用当前目录中的z.txt。它没有父文件对象,因此f3.getParent()f3.getParentFile()将返回null。

答案 4 :(得分:0)

路径是完整路径

如果您只需要调用file.getParent()

所需的目录