I want to check if a given String is a file or a directory, i've tried the methods isFile() and isDirectory() of the File class but the problem is that if the directory or file doesn't exist these methods returns false, because as stated in the javadoc :
isFile() :
true if and only if the file denoted by this abstract pathname exists
and is a normal file; false otherwise
isDirectory() :
true if and only if the file denoted by this abstract pathname exists
and is a directory; false otherwise
Basically i need two methods without the exist clause ...
So i want to test if the given string complies to a directory format or complies to a file format, in a multiplatform context (so, should work on Windows, Linux and Mac Os X).
Does exist some library that provide these methods ? What could be the best implementation of these methods ?
UPDATE
In the case of a string that could be both(without extension) by default should be identified as directory, if a file with that path does not exist.
So i want to test if the given string complies to a directory format or complies to a file format, in a multiplatform context (so, should work on Windows, Linux and Mac Os X).
In Windows, a directory can have an extension and a file is not required to have an extension. So, you can't tell just by looking at the string.
If you enforce a rule that a directory doesn't have an extension, and a file always has an extension, then you can determine the difference between a directory and a file by looking for an extension.
Why not just wrap them in a call to File#exists()?
File file = new File(...);
if (file.exists()) {
// call isFile() or isDirectory()
}
By doing that, you've effectively negated the "exists" portion of isFile() and isDirectory(), since you're guaranteed that it does exist.
It's also possible that I've misunderstood what you're asking here. Given the second part of your question, are you trying to use isFile() and isDirectory() on non-existent files to see if they look like they're files or directories?
If so, that's going to be tough to do with the File API (and tough to do in general). If /foo/bar/baz doesn't exist, it's not possible to determine whether it's a file or a directory. It could be either.
Sounds like you know what you want, according to your update: if the path doesn't exist and the path has an extension it's a file, if it doesn't it's a directory. Something like this would suffice:
private boolean isPathDirectory(String myPath) {
File test = new File(myPath);
// check if the file/directory is already there
if (!test.exists()) {
// see if the file portion it doesn't have an extension
return test.getName().lastIndexOf('.') == -1;
} else {
// see if the path that's already in place is a file or directory
return test.isDirectory();
}
}
There are rules for what is invalid in a file and/or folder name. For example, Windows doesn't allow *, ?, and a few other characters. Based on what's invalid, you could build a regex expression or some other process/checking system to see if it looks like a file or folder.
This could get complex as you want it to work for many different OS's. Also, as previously posted, there would be no way to tell a file from a folder unless you artificially enforced a convention. For example, directories must end in a front-slash / in Windows.
Having the IF EXISTS check first would help. If IF EXISTS = true, then running the existing File.isDirectory() or File.isFile() code would simplify a lot of this. You would only have to write code for when IF EXISTS = false.
Related
I want to be able to iterate through a package of files as if the package were a folder.
Something like the below (scripts being the java package):
File scriptFolder = new File("scripts").getAbsoluteFile();
The packages appear are not being treated like folders. If I hardcode the path C:\Users\...\project_folder\...\scripts the File.isFile() method returns false for the package. If I do new File (C:\Users\...\project_folder\...\scripts\script).isFile() I get true.
I want to get a File of the folder so I can get a list of the files in the folder and iterate through it.
The .isFile() method returns true only if you are referencing a plain jane normal file. If you're referencing a directory, it'd return false. Try .isDirectory() or possibly .exists().
Or don't; there's no real need:
File[] filesInDir = new File("C:\\Users\\....\\scripts").listFiles();
if (filesInDir == null) {
// this means it wasn't a directory or didn't exist or isn't readable
} else {
for (File child : filesInDir) {
// called for each file in dir
}
}
The official javadocs say this about File#isFile():
Tests whether the file denoted by this abstract pathname is a normal file. A file is normal if it is not a directory and, in addition, satisfies other system-dependent criteria. Any non-directory file created by a Java application is guaranteed to be a normal file.
You can check if it is a directory with File#isDirectory(), then if it is, you can list its contents with File#listFiles().
Unless I'm missing something in your question C:\Users...\project_folder...\scripts is a directory so isFile() will return false because it is not a file.
I am currently programming a file name normaliser. Files have a format and folders dont. When I rename a file I need to make sure that I do not affect the format therefore I did
fileName.substring(fileName.lastIndexOf("."),fileName.length)
thereby if I want to replace all the periods in a fileName it does not affect the format, when a folder with periods in its name goes through this process, the last instance of the period is still part of its name, therefore it does not replace all the dots in the folders name. I need to know how to distinguish between a file and a folder so I can fix this.
You can use
someFile.isDirectory();
It returns true if the file is a folder, and false if not.
You can use File.isDirectory() to test whether the file denoted by this abstract pathname is a directory. You can also use File.isFile() to test whether the file denoted by this abstract pathname is a normal file. A file is normal if it is not a directory and, in addition, satisfies other system-dependent criteria.
File f = new File(fileName);
if (f.isFile()) {
// it's a file.
} else if (f.isDirectory()) {
// it's a directory.
}
I need a File object pointing to a directory (may not be existing). How do I do that?
Even if I do something like
File dir = new File("/tmp/something/"); // with trailing slash
dir.isDirectory() is false. Then I tried dir.mkdir() which returns false, why? I dont need the directory to be existing, in fact, I want it to point to a directory that does not exist (I am doing testing). How can I achieve this?
from javadoc: "true if and only if the file denoted by this abstract pathname exists and is a directory"
If the file does not exists isDirectory() return false. If you are doing testing probably use a stub can be a better option, in unit testing its better try to don't touch external resources like the filesystem.
Use dir.mkdirs()
mkdirs() will create the specified directory path in its entirety where mkdir() will only create the bottom most directory, failing if it can't find the parent directory of the directory it is trying to create.
Trailing slash does not matter. File.isDirectory returns false because it returns true if and only if the file denoted by this abstract pathname exists and is a directory
I have a file with name "aaaäaa.xls"
For this, File.isFile() and File.isDirectory() is returning false? why it is returning false in Linux?
Please try the following code example
if(!pFile.exists()){
throw new FileNotFoundException();
}
boolean isDir = pFile.isDirectory();
boolean isFile = pfile.isFile();
the file is not a file
if it is not a directory and, in addition, satisfies other system-dependent criteria
if the exception is thrown, you have to check the file path.
According to the documentation:
public boolean isFile()
Returns:
true if and only if the file denoted by this abstract pathname exists and is
a normal file; false otherwise.
From this basis, your file either doesn't exist or is not a normal file.
Possible reasons of the 1st:
file doesn't exist;
file can't be accessed;
file name is mistyped;
the character encoding used in your program isn't the
same as that used when you created the file.
Possible reasons of the 2nd:
it's not a regular file.
Or it's a bug in JVM. It's also possible though unlikely. For example at once I had problems with an exclamation mark in path names - Bug 4523159.
If you want to access the file in any way, consider calling dir.listFiles() and work with its return value.
(answer is partially based on this thread)
Check the permissions of the parent directories of this file. Some of these directories may not have execute permission for the current user.
The execute bit of directory allows the affected user to enter it and access files and directories inside
I know that this question was asked five years ago, in fact, I got to it because I had the same problem, I am creating a List of all the files in a given path, like this:
File files = Paths.get(path).toFile();
List<String> filenames = Arrays.asList(files.list());
The thing is, that path contains a directory which is called testing_testing, which is being returned as part of the list.
Then when I do the following test:
for (String filename : filenames) {
if (Files.isDirectory(Paths.get(filename))) {
System.out.println(filename + " is a directory.");
} else {
if(filename.equals("testing_testing")) {
System.out.println("Is this a directory?: " + Files.isDirectory(Paths.get(filename)));
System.out.println("Does the file exists?: " + Files.exists(Paths.get(filename)));
System.out.println("Is this a regular file?: " + Files.isRegularFile(Paths.get(filename)));
System.out.println("Is this a symbolic link?: " + Files.isSymbolicLink(Paths.get(filename)));
}
}
}
It is returning false for Files.isDirectory() and for Files.exists().
Tinkering around for a bit, I noticed that I was only getting the filenames, without the full path to them, which meant that I was only passing testing_testing to Paths.get() instead of passing the full path to get to it, that's why it didn't exists and returned false for both scenarios.
I changed the code to:
Paths.get("C:\test", filename);
And now the tests return the proper values. I don't know if you've already figured this out, because it's been five years since you asked. But for anyone with the same problem, make sure that you're passing the correct path to your files, and then try the other things suggested in previous answers on this same question.
I've also had problems with file.isFile() returning false on files, presumably because the file is not "regular", as noted in other responses to this question. As a workaround, I use file.listFiles() != null, which seems to provide the functionality I need. According to the Java File API:
If this abstract pathname does not denote a directory, then this method returns null. Otherwise an array of File objects is returned.
I got same error when i was testing isFile() on a .txt file.
The problem was the file i created had something.txt with .txt on the name.
Then i renamed something.txt to something
I was really mad with myself
The character encoding used by Java in your case is different from the character encoding in the source file, so the symbol "ä" in the file name cannot be properly decoded by Java, resulting in a different file name. That's why Java cannot find the file. Therefore, the file manipulation functions over this file return "False".
As the safest way to work properly in different build environments, to avoid setting Java character encoding option and also make handling source files easier, use US-ASCII only (7-bit) characters in the source code. As for the other characters, use their Unicode numbers, e.g., instead of "ä" use "\u00e4". So, your filename would become "aaa\u00e4aa.xls".
I've had this issue several times and if everything has been tried then it might be that you have issues with pathing. Any space character is replaced by %20, and it results in an issue.
Therefore, whereas this doesn't work:
File file = new File(Objects.requireNonNull(getClass().getResource(/path/to/file).getPath());
This actually does:
File file = new File(Objects.requireNonNull(getClass().getResource(/path/to/file).getPath().replace("%20", " "));
A program we have erred when trying to move files from one directory to another. After much debugging I located the error by writing a small utility program that just moves a file from one directory to another (code below). It turns out that while moving files around on the local filesystem works fine, trying to move a file to another filesystem fails.
Why is this? The question might be platform specific - we are running Linux on ext3, if that matters.
And the second question; should I have been using something else than the renameTo() method of the File class? It seems as if this just works on local filesystems.
Tests (run as root):
touch /tmp/test/afile
java FileMover /tmp/test/afile /root/
The file move was successful
touch /tmp/test/afile
java FileMover /tmp/test/afile /some_other_disk/
The file move was erroneous
Code:
import java.io.File;
public class FileMover {
public static void main(String arguments[] ) throws Exception {
boolean success;
File file = new File(arguments[0]);
File destinationDir = new File(arguments[1]);
File destinationFile = new File(destinationDir,file.getName() );
success = file.renameTo(destinationFile);
System.out.println("The file move was " + (success?"successful":"erroneous"));
}
}
Java 7 and above
Use Files.move(Path source, Path target, CopyOption... opts).
Note that you must not provide the ATOMIC_MOVE option when moving files between file systems.
Java 6 and below
From the docs of File.renameTo:
[...] The rename operation might not be able to move a file from one filesystem to another [...]
The obvious workaround would be to copy the file "manually" by opening a new file, write the content to the file, and delete the old file.
You could also try the FileUtils.moveFile method from Apache Commons.
Javadoc to the rescue:
Many aspects of the behavior of this method are inherently
platform-dependent: The rename operation might not be able to move a
file from one filesystem to another, it might not be atomic, and it
might not succeed if a file with the destination abstract pathname
already exists. The return value should always be checked to make sure
that the rename operation was successful.
Note that the Files class defines the move method to move or rename a
file in a platform independent manner.
From the docs:
Renames the file denoted by this abstract pathname.
Many aspects of the behavior of this method are inherently
platform-dependent: The rename operation might not be able to move a
file from one filesystem to another, it might not be atomic, and it
might not succeed if a file with the destination abstract pathname
already exists. The return value should always be checked to make sure
that the rename operation was successful.
If you want to move file between different file system you can use Apache's moveFile
your ider is error
beause /some_other_disk/ is relative url but completely url ,can not find the url
i have example
java FileMover D:\Eclipse33_workspace_j2ee\test\src\a\a.txt D:\Eclipse33_workspace_j2ee\test\src
The file move was successful
java FileMover D:\Eclipse33_workspace_j2ee\test\src\a\a.txt \Eclipse33_workspace_j2ee\test\src
The file move was erronous
result is url is error