Check if file exists without creating it - java

If I do this:
File f = new File("c:\\text.txt");
if (f.exists()) {
System.out.println("File exists");
} else {
System.out.println("File not found!");
}
Then the file gets created and always returns "File exists". Is it possible to check if a file exists without creating it?
EDIT:
I forgot to mention that it's in a for loop. So here's the real thing:
for (int i = 0; i < 10; i++) {
File file = new File("c:\\text" + i + ".txt");
System.out.println("New file created: " + file.getPath());
}

When you instantiate a File, you're not creating anything on disk but just building an object on which you can call some methods, like exists().
That's fine and cheap, don't try to avoid this instantiation.
The File instance has only two fields:
private String path;
private transient int prefixLength;
And here is the constructor :
public File(String pathname) {
if (pathname == null) {
throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}
As you can see, the File instance is just an encapsulation of the path. Creating it in order to call exists() is the correct way to proceed. Don't try to optimize it away.

Starting from Java 7 you can use java.nio.file.Files.exists:
Path p = Paths.get("C:\\Users\\first.last");
boolean exists = Files.exists(p);
boolean notExists = Files.notExists(p);
if (exists) {
System.out.println("File exists!");
} else if (notExists) {
System.out.println("File doesn't exist!");
} else {
System.out.println("File's status is unknown!");
}
In the Oracle tutorial you can find some details about this:
The methods in the Path class are syntactic, meaning that they operate on the Path instance. But eventually you must access the file system to verify that a particular Path exists, or does not exist. You can do so with the exists(Path, LinkOption...) and the notExists(Path, LinkOption...) methods. Note that !Files.exists(path) is not equivalent to Files.notExists(path). When you are testing a file's existence, three results are possible:
The file is verified to exist.
The file is verified to not exist.
The file's status is unknown. This result can occur when the program does not have access to the file.
If both exists and notExists return false, the existence of the file cannot be verified.

Creating a File instance does not create a file on the file system, so the posted code will do what you require.

The Files.exists method has noticeably poor performance in JDK 8, and can slow an application significantly when used to check files that don't actually exist.
This can be applied too for Files.noExists, Files.isDirectory and Files.isRegularFile
According this you can use the following :
Paths.get("file_path").toFile().exists()

Related

The .delete() method in java is not working

Files inside the (Tracks)directory was not deleted. The method deletes the wav files stored in the directory.
public boolean deleteTrack(response) {
ListIterator<Track> trackListIterator = this.trackList.listIterator();
//tracklist is the linked list on which I'm using list iterator. I'm storing song which is a object inside it. this object has a fn() that returns content root path not absolute path.
String path = "";
while (trackListIterator.hasNext()) {
//RESPONSE == PARAMETER
if (trackListIterator.next().getTrackName().equals(response)) {
trackListIterator.previous();
path = trackListIterator.next().getTrackPath();//this is the fn() that
returns content root path example(src/Exploit/org/Trackstore/Music/Action Movie Music-FesliyanStudios.wav).
break;
}
}
File file = new File(path);
//here I'm taking absolute path for deleting actual wav file from the computer.
File toBeDeleted = new File(file.getAbsolutePath());
return toBeDeleted.delete();// returns false everytime.
}
The old API has many issues. For example, most methods return a boolean to indicate the result which is stupid and unjavalike - fortunately, there is a new API that fixes these issues.
Use it and you'll know WHY it failed. If that's too much effort, well, there isn't much to say. It didn't delete. No idea why, and there's no way to ask that API about why.
The new API lives in the java.nio.file package.
Replace this:
File f = new File("path/to/file");
if (!f.delete()) { ... it didn't work ... }
with:
Path p = Paths.get("path/to/file");
try {
Files.delete(p);
} catch (IOException e) {
// the exception will explain everything there is to be said about why it did not work!
}

File Handling issue in Multi threaded Environment

I am facing a strand kind of issue in multi threaded environment.
Though this code was pretty old and was working since long time.
One of the person complained that they are facing issue like. Even
though the file created by one thread exist , another thread saying no
file exist.
I providing a sample method where the problem is coming..
/**
* Creates a temporary directory. Will be deleted when the program closed if it
* is empty!
*
* #return the temporary directory
* #throws com.osm.exception.WMException if there is a problem
*/
public static File createTempDir() throws WMException {
synchronized (pdm.semaphore) {
try {
final File parent = WMSession.getWMSession().getRootTempDir();
if (!parent.exists()) {
throw new IllegalStateException(parent + " does not exist"); //frozen
}
final File tmpDirectory = File.createTempFile("WMTempDir", "", parent); //frozen
tmpDirectory.delete();
tmpDirectory.mkdirs();
logFileCreated(tmpDirectory);
return tmpDirectory;
} catch (final IOException ioe) {
throw new WMException(ioe);
}
}
}
This code is being called from another method code as below.
void copy_from_db2_using_temp_dir(String phys_name, int storage_type, int store_date, int file_flag,
String directory, String file_name) throws WMException {
final File destDir = new File(directory);
if (!destDir.exists()) {
// no conflict possible since destination directory does not yet exist.
pdm.copy_from_db2(phys_name, storage_type, store_date, file_flag, directory, file_name);
return;
}
final File tmpDir = WMFile.createTempDir();
final File tmpDestFile = new File(tmpDir, file_name);
final File destFile = new File(directory, file_name);
try {
final boolean destFileExistsFlag = destFile.exists();
if (destFileExistsFlag && (file_flag != DEL_OLD)) {
final String msg = pdm.fix_mesg(pdm.catgets("data_mgr", 266, "*** ERROR: Cannot overwrite file '{1}'"),
destFile.getAbsolutePath());
throw new WMException(msg);
}
pdm.copy_from_db2(phys_name, storage_type, store_date, file_flag, tmpDir.getAbsolutePath(), file_name);
if (tmpDestFile.isFile() && destFile.isDirectory()) {
final String msg = pdm.fix_mesg(pdm.catgets("data_mgr", 269, "*** ERROR: Could not remove file '{1}'"),
destFile.getAbsolutePath());
throw new WMException(msg);
}
moveFiles(tmpDestFile, destFile, (file_flag == DEL_OLD));
} finally {
deleteTempDir(tmpDir);
}
}
The another thread/process always getting the condition
!parent.exists() true. Which is incorrect as it must get the parent
file.
Need suggestion input or any logging that will helpful to know if the
invocation has some issue or some issue in the code.
I got something on StackOverflow but not sure if that is relevant
here.
File.exists() issue in multi threaded env
if (!parent.exists()) { in your createTempDir function is triggered, because the parentFolder of the file that you are trying to create does not exist. This has nothing to do with multithreading.
Example:
Lets say we are trying to create the folder C:\myGame\logs in the createTempDir method. Your code will first test to see if C:\myGame exists. If it does not exist, then your code will throw an illegal state exception and not continue execution.
In other words: the parent directory in which you want to create your logs directory does not exist. This could be due to a number of reasons:
WMSession.getWMSession().getRootTempDir() is not properly configured: it points to a wrong filepath.
Perhaps you don't even need to assert that the parent directory exists. Because you call mkdirs() in your code, all required ancestor-directories for your logs directory will be automatically created.
You can consider the following solutions:
Properly configure WMSession so that it points to the correct folder, assuming that you want the parent directory to exist in advance of your code execution.
Simply don't care about if the parent directory exists, as mkdirs handles this for you.

how to check if the file path is invalid/does not exist in java

My task is to save a file in the path specified by the end user (must be an absolute path). Am currently facing three different scenarios as in below:
Path name is invalid (cannot be created) - for ex, path name provided by user : sfg rgdf gfggdgfudf
Path name is invalid (but, it can be created) - for ex : C:\Parent\Child\GrandChildren (here C:\Parent exists whereas Child\GrandChildren does not.
Path name is valid (i.e. directory exists) - for ex : C:\Parent\Test
For the first case, I need to save the file in a default location.
For the second, I need to create directories and save the file.
And for the last, I'll save in the specified path.
Below is my code snippet which is saving the file in default location for both first and second scenarios. Am having difficulty to distinguish between first and second. java.io.File.mkdirs works for the second case, but not for the first.
Please ignore my poor code as am new to this programming language. Any inputs would be much appreciated.
//User input must be absolute path
String saveToFolder = "kut igeiguye jh";
String defaultFolder = "C:\\Parent\\Data";
try{
File file = new File(saveToFolder);
if(!file.exists()){
saveToFolder = defaultFolder;
}
file.mkdirs();
}catch(Exception e){
saveToFolder = defaultFolder;
}
//code to save data in path **saveToFolder**
1) For 1st case use regex to determine if path is valid or not
String regularExpression = "([a-zA-Z]:)?(\\[a-zA-Z0-9_-]+)+\\?" ; // this regex for windows. If you are running in linux then regex will be different.
Pattern pattern = Pattern.compile(regularExpression);
boolean isMatched = Pattern.matches(regularExpression,saveToFolder);
2) Check if path is valid or not again using 1st method. If its valid check if folder exists or not.
File f = new File(saveToFolder);
if (f.exists() && f.isDirectory()) {
...
}
3) If path is valid by first method and if it exists second method .
kut igeiguye jh is happily accepted by most file systems out there. If you don't want spaces in your path/filenames, you already need to check the validity by yourself e.g. using a Regular Expression.
Appreciate all those who added their inputs. I made few changes to my code which works. One of my assignments requirement was that my program must take absolute path as input.
With my below code, am able to save data in default location for case 1; New folders are being created and file is being saved in the newly created folder for case 2; And saving the file in specified path for case 3.
String saveToFolder = "kut igeiguye jh";
String defaultFolder = "C:\\Parent\\Data";
try{
File file = new File(saveToFolder);
boolean dirCreated = file.mkdirs();
if(!dirCreated || (file.getParent().equals(null))){
saveToFolder = defaultFolder;
}
}catch(Exception e){
saveToFolder = defaultFolder;
}
System.out.println("save to folder : " +saveToFolder);
you can use isFile() to valid over exists(). I have not checked for all cases but this should help you.
public static void checkPath(){
String saveToFolder = "file/User.txt";
String defaultFolder = "file/data/";
try{
File file = new File(saveToFolder);
if(!file.isFile()){
saveToFolder = defaultFolder;
System.out.println("File not found");
}
file.mkdirs();
}catch(Exception e){
saveToFolder = defaultFolder;
}
}
Java NIO make this simple. The method Files.createDirectories succeeds whether the directory already exists or didn't exist and has been created.
try {
Files.createDirectories(Paths.get(saveToFolder));
}
catch (IOException e) {
System.err.println("Using default folder due to the following exception: " + e);
saveToFolder = defaultFolder;
}
If you really want to check whether the user entered an absolute path, just use Path.isAbsolute().

File.renameTo() doesn't have any effect

I'd like to be able to rename a list of folders in order to remove unwanted characters (a dot and double space have to become a single space, for example).
Upon clicking a button in the Gui, you'll see a messagebox with the correctly formatted name appear which indicates that both the formatting is correct and the function is called.
When I look at the test folders I've created, the names aren't changed (not even after refreshing). Using a hardcoded string doesn't work either.
What am I overlooking?
public void cleanFormat() {
for (int i = 0; i < directories.size(); i++) {
File currentDirectory = directories.get(i);
for (File currentFile : currentDirectory.listFiles()) {
String formattedName = "";
formattedName = currentFile.getName().replace(".", " ");
formattedName = formattedName.replace(" ", " ");
currentFile.renameTo(new File(formattedName));
JOptionPane.showMessageDialog(null, formattedName);
}
}
}
For future browsers: This was fixed with Assylias' comment. Below you will find the eventual code which fixed it.
public void cleanFormat() {
for (int i = 0; i < directories.size(); i++) {
File currentDirectory = directories.get(i);
for (File currentFile : currentDirectory.listFiles()) {
String formattedName = "";
formattedName = currentFile.getName().replace(".", " ");
formattedName = formattedName.replace(" ", " ");
Path source = currentFile.toPath();
try {
Files.move(source, source.resolveSibling(formattedName));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Well, first of all the File.renameTo is trying to rename a file on the same filesystem.
The following is from java doc
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 call to getName() returns just the name of the file and not any directory information. So you may be trying to rename the file to a different directory.
Try adding the containing directory to the file object you pass into rename
currentFile.renameTo(new File(currentDirectory, formattedName));
Also like others have said you should be checking the return value of renameTo which is probably false, or use the new methods in Files class which I've found to throw pretty informative IOExceptions.
First of all check return value, File.renameTo returns true if the renaming succeeded; false otherwise. E.g. you cannot rename / move a file from c: to d: on Windows.
And most importantly, use Java 7's java.nio.file.Files.move instead.

Java 'file.delete()' Is not Deleting Specified File

This is currently what I have to delete the file but it's not working. I thought it may be permission problems or something but it wasn't. The file that I am testing with is empty and exists, so not sure why it doesn't delete it.
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
file.delete();
Any help would be GREATLY appreciated!
I now have:
File file = new File(catName + ".txt");
String path = file.getCanonicalPath();
File filePath = new File(path);
filePath.delete();
To try and find the correct path at run time so that if the program is transferred to a different computer it will still find the file.
The problem could also be due to any output streams that you have forgotten to close. In my case I was working with the file before the file being deleted. However at one place in the file operations, I had forgotten to close an output stream that I used to write to the file that was attempted to delete later.
Be sure to find out your current working directory, and write your filepath relative to it.
This code:
File here = new File(".");
System.out.println(here.getAbsolutePath());
... will print out that directory.
Also, unrelated to your question, try to use File.separator to remain OS-independent. Backslashes work only on Windows.
I got the same problem! then realized that my directory was not empty. I found the solution in another thread: not able to delete the directory through Java
/**
* Force deletion of directory
* #param path
* #return
*/
static public boolean deleteDirectory(File path) {
if (path.exists()) {
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return (path.delete());
}
Try closing all the FileOutputStream/FileInputStream you've opened earlier in other methods ,then try deleting ,worked like a charm.
I suspect that the problem is that the path is incorrect. Try this:
UserInput.prompt("Enter name of file to delete");
String name = UserInput.readString();
File file = new File("\\Files\\" + name + ".txt");
if (file.exists()) {
file.delete();
} else {
System.err.println(
"I cannot find '" + file + "' ('" + file.getAbsolutePath() + "')");
}
If you want to delete file first close all the connections and streams.
after that delete the file.
In my case it was the close() that was not executing due to unhandled exception.
void method() throws Exception {
FileInputStream fis = new FileInputStream(fileName);
parse(fis);
fis.close();
}
Assume exception is being thrown on the parse(), which is not handled in this method and therefore the file is not closed, down the road, the file is being deleted, and that delete statement fails, and do not delete.
So, instead I had the code like this, then it worked...
try {
parse(fis);
}
catch (Exception ex) {
fis.close();
throw ex;
}
so basic Java, which sometimes we overlook.
As other answers indicate, on Windows you cannot delete a file that is open. However one other thing that can stop a file from being deleted on Windows is if it is is mmap'd to a MappedByteBuffer (or DirectByteBuffer) -- if so, the file cannot be deleted until the byte buffer is garbage collected. There is some relatively safe code for forcibly closing (cleaning) a DirectByteBuffer before it is garbage collected here: https://github.com/classgraph/classgraph/blob/master/src/main/java/nonapi/io/github/classgraph/utils/FileUtils.java#L606 After cleaning the ByteBuffer, you can delete the file. However, make sure you never use the ByteBuffer again after cleaning it, or the JVM will crash.

Categories