49

I have a method that writes to a log file. If the file exists it should append to it, if not then I want it to create a new file.

if (!file.exists() && !file.createNewFile()) {
    System.err.println("Error with output file: " + outFile
        + "\nCannot create new file.");
    continue;
}

I have that to check that a file can be created. file is a java.io.File object. createNewFile is throwing an IOException: No such file or directory. This method has been working perfectly since I wrote it a few weeks ago and has only recently starting doing this although I don't know what I could have changed. I have checked, the directory exists and I have write permissions for it, but then I thought it should just return false if it can't make the file for any reason.

Is there anything that I am missing to get this working?

A Jackson
  • 2,776
  • 7
  • 34
  • 45

10 Answers10

129

try to ensure the parent directory exists with:

file.getParentFile().mkdirs()
Omry Yadan
  • 31,280
  • 18
  • 64
  • 87
  • I have done this but still I get the error - `if (!outputFile.getParentFile().exists()) outputFile.getParentFile().mkdirs(); if (!outputFile.exists() && !outputFile.createNewFile()) logger.error("Failed to create file"); ` – Chetan Oswal May 04 '23 at 12:18
20

Perhaps the directory the file is being created in doesn't exist?

Miserable Variable
  • 28,432
  • 15
  • 72
  • 133
8

normally this is something you changed recently, first off your sample code is if not file exists and not create new file - you are trying to code away something - what is it?

Then, look at a directory listing to see if it actually exists and do a println / toString() on the file object and getMessage() on the exception, as well as print stack trace.

Then, start from zero knowledge again and re factor from the get-go each step you are using to get here. It's probably a duh you stuck in there somewhere while conceptualizing in code ( because it was working ) - you just retrace each step in detail, you will find it.

Nicholas Jordan
  • 638
  • 3
  • 6
  • 1
    Thanks. I spent a while going back through everything and found where it reads the path from a cfg file it wasn't removing a colon. output_file:path When it was last working I hadn't done the cfg file yet, it was a hard coded path. – A Jackson Oct 06 '09 at 12:43
  • 1
    @Android: Just curious: Is this any different from what I recommended in http://stackoverflow.com/questions/1525060/file-createnewfile-thowing-ioexception-no-such-file-or-directory/1525073#1525073? – Miserable Variable Oct 06 '09 at 14:55
  • 1
    @Hemal Pandya - I saw your comment, and as noted it is correct - I just have been through this so many times i thought I could word it better for the poster. @Android - remember this lesson well, let it constantly be with you. World class operations have been completely bamboozled by this a sufficient number of times that carefully crafted recovery is a super-critical central skill, one that only comes with doing this type of recovery work. Use some type of Feed-Forward archive, with gig drives available at hand, there is no reason to lose recoverable trails. – Nicholas Jordan Oct 09 '09 at 22:45
  • Was no dir in my case. – Vadim Jan 19 '17 at 03:01
8

I think the exception you get is likely the result from the file check of the atomic method file.createNewFile(). The method can't check if the file does exist because some of the parent directories do not exist or you have no permissions to access them. I would suggest this:

if (file.getParentFile() != null && !file.getParentFile().mkdirs()) {
    // handle permission problems here
}
// either no parent directories were there or we have created missing directories
if (file.createNewFile() || file.isFile()) {
    // ready to write your content
} else {
    // handle directory here
}

If you take concurrency into account, all these checks are useless because in every case some other thread is able to create, delete or do anything else with your file. In this case you have to use file locks which I would not suggest doing ;)

Muktadir Khan
  • 148
  • 3
  • 17
3

According to the [java docs](http://java.sun.com/j2se/1.5.0/docs/api/java/io/File.html#createNewFile() ) createNewFile will create a new file atomically for you.

Atomically creates a new, empty file named by this abstract pathname if and only if a file with this name does not yet exist.

Given that createNewFile is atomic and won't over-write an existing file you can re-write your code as

try {
    if(!file.createNewFile()) {
        System.out.println("File already exists");
    } 
} catch (IOException ex) {
    System.out.println(ex);
}

This may make any potential threading issues, race-conditions, etc, easier to spot.

Glen
  • 21,816
  • 3
  • 61
  • 76
  • You shouldn't just log an exception, except when the operation was really not vital to your program. If `createNewFile` throws an exception then it's safe to assume that you either wanted that file to be created (it wasn't -> bad) or you wanted to later write to it (will result in an exception -> bad). In any case it's good to fail fast and let the caller decide how to procede. – Cecilya Jul 04 '18 at 07:51
3

You are certainly getting this Exception 'The system cannot find the path specified'

Just print 'file.getAbsoluteFile()' , this will let you know what is the file you wanted to create.

This exception will occur if the Directory where you are creating the file doesn't exist.

Rakesh Juyal
  • 35,919
  • 68
  • 173
  • 214
2
//Create New File if not present
if (!file.exists()) {
    file.getParentFile().mkdirs();

    file.createNewFile();
    Log.e(TAG, "File Created");
}
Nubok
  • 3,502
  • 7
  • 27
  • 47
Ganesan J
  • 539
  • 7
  • 12
0

This could be a threading issue (checking and creating together are not atomic: !file.exists() && !file.createNewFile()) or the "file" is already a directory.

Try (file.isFile()) :

if (file.exists() && !file.isFile()){
   //handle directory is there
}else if(!file.createNewFile()) {
   //as before
}
Thomas Jung
  • 32,428
  • 9
  • 84
  • 114
  • Have you read the JavaDocs for createNewFile? Checking and creating is indeed an atomic operation and hence thread safe. – jarnbjo Oct 06 '09 at 12:02
  • 2
    file.exist() is atomic and file.createNewFile is atomic. But between these two calls concurrent changes can occur. – Thomas Jung Oct 06 '09 at 14:18
  • just have a look at this answer: http://stackoverflow.com/questions/1525060/file-createnewfile-thowing-ioexception-no-such-file-or-directory/1525132#1525132 – Thomas Jung Oct 06 '09 at 14:19
  • agree with Thomas, he's talking about a threading issue. The statement "!file.exists() && !file.createNewFile()" calls two methods on the "file" object. While both methods are atomic, other code running at the same time can create the file between these two atomic actions. Refer to: http://en.wikipedia.org/wiki/Race_condition – Leo Lansford Jun 05 '13 at 15:22
0

In my case was just a lack of permission:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

dianakarenms
  • 2,609
  • 1
  • 22
  • 22
-1

Use

yourAppsMainActivityContext.getExternalCacheDir()

instead of

Environment.getExternalStorageDriectory()

to get the file storage path.

Alternatively, you can also try getExternalFilesDir(String type), getExternalCacheDir(), getExternalMediaDirs().

Gene
  • 10,819
  • 1
  • 66
  • 58