开发者

Java can't get the path of a file that exists in the current directory

开发者 https://www.devze.com 2023-03-29 18:09 出处:网络
If a file exists in the same directory where a Java application is running and I create a File object for that file the Java File methods for the path of the file include the filename as well.Code and

If a file exists in the same directory where a Java application is running and I create a File object for that file the Java File methods for the path of the file include the filename as well. Code and output are below.

If this was a bug in the JDK version I'm using someone would surely have seen it by now.

Why do File.getAbsolutePath() and File.getCanonicalPath() include the file name? The Javadocs indicate that the directory name should be returned.

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();
        }
    }

}

Here' the output:

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

So far the only way I've found to get the directory in this case is to manually parse off the file name.

Does the File class have a way to get the directory name in this case (where a File that exists in the current directory is created without specifying a directory)?


Why do File.getAbsolutePath() and File.getCanonicalPath() include the file name? The Javadocs indicate that the directory name should be returned.

No, they don't. If you'd care to point out why you think they do, someone can probably identify the mistake in your reasoning. Also, if you specify exactly what you'd like to see for output given some particular input, we can help you out there, too. Your question title seems strange, too, since your problem seems to be that it is returning the full path to a file.

Edit: I think I understand the source of your confusion. A File represents a file system path in a platform-agnostic way. It can be a path to a file or to a directory. It also always represents the same path, though not necessarily the same absolute path. This is a very fine distinction but a very important one. A File object representing a relative path is always relative. Given a File representing a relative path, you can get the current corresponding absolute path using getAbsolutePath(). This doesn't, however, alter the fact that the File represents a relative path. Further invocations of getAbsolutePath() on the same File object may return different values. Consider, for example:

// 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

It should be clear now that the path a File represents is only that: a path. Further, a path can be composed of zero or more parts, and calling getParent() on any File gives back the path of that File with the last path element removed unless there isn't a "last path element" to remove. Thus the expected result of new File("foo").getParent() is null since the relative path "foo" has no parent.

From the example and explanation above, you should be able to see that the way to get the containing directory when you've created relative-path File object is with

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

with the caveat that the "absolute path" depends on your environment at the time.

Additional note: Since File is Serializable, you could write a relative-path file to disk or send it across a network. That File, when deserialized in another JVM, will still represent a relative path and will be resolved against whatever the current working directory of that JVM happens to be.


The behaviour is expected. The documentation does not mention that the filename is not included.

Perhaps you are confused by the difference between getAbsolutePath() and getAbsoluteFile(). It's that the latter returns a File instance.


I'm not sure why you think the Javadoc says that it returns the directory name.

Here is the Javadoc --

An abstract representation of file and directory pathnames.

User interfaces and operating systems use system-dependent pathname strings to name files and directories. This class presents an abstract, system-independent view of hierarchical pathnames. An abstract pathname has two components:

  1. An optional system-dependent prefix string, such as a disk-drive specifier, "/" for the UNIX root directory, or "\\" for a Microsoft Windows UNC pathname, and
  2. A sequence of zero or more string names.

The first name in an abstract pathname may be a directory name or, in the case of Microsoft Windows UNC pathnames, a hostname. Each subsequent name in an abstract pathname denotes a directory; the last name may denote either a directory or a file. The empty abstract pathname has no prefix and an empty name sequence.

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

Returns the absolute pathname string of this abstract pathname.


In addition to the existing answers with regards to getAbsolutePath and getCanonicalPath, please also note, that File.getParent() does not mean "parent directory" it merely refers to the parent file object that was used to create the file.

For example, if the file object can be created as such:

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 would refer to /path/to/a/directory/x.txt, it's parent is dir (/path/to/a/directory)

f2 would refer to /path/to/a/directory/../another/y.txt, it's canonical path would be /path/to/a/another/y.txt, but it's parent is still the reference to dir (/path/to/a/directory)

f3 would refer to z.txt in the current directory. It does not have a parent file object, so f3.getParent() or f3.getParentFile() would return null.


path is the full path

if you only want the directory you need to call file.getParent()

0

精彩评论

暂无评论...
验证码 换一张
取 消