49

I'm trying to open a file in android like this :

  try
   {
      FileInputStream fIn = context.openFileInput(FILE);
      DataInputStream in = new DataInputStream(fIn);
      BufferedReader br = new BufferedReader(new InputStreamReader(in));
      if(in!=null)
          in.close();
   }
   catch(Exception e)
   {  }

, but in case the file does not exists a file not found exception is thrown . I'd like to know how could I test if the file exists before attempting to open it.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
rantravee
  • 7,411
  • 9
  • 35
  • 47
  • 2
    If that's your actual exception handler, rethink it. http://www.rockstarprogrammer.org/post/2007/jun/15/empty-catch-blocks-are-always-wrong/ – Thomas May 07 '10 at 08:16
  • @Thomas that used to be MY exception handler for a clause just like this one (copied some code off the 'Net.) I guess a good rule for copying is to examine everything before you actually use it. I have enough trouble using my OWN code. –  Aug 29 '12 at 21:13
  • Possible duplicate of [Android; Check if file exists without creating a new one](https://stackoverflow.com/questions/16237950/android-check-if-file-exists-without-creating-a-new-one) (I know this Q is older, but that other has more upvotes in general, and is more updated to current Android) – DarkCygnus Jul 25 '19 at 00:13

7 Answers7

162

I think the best way to know if a file exists, without actually trying to open it, is as follows:

File file = getContext().getFileStreamPath(FILE_NAME);
if(file.exists()) ...
starball
  • 20,030
  • 7
  • 43
  • 238
lencinhaus
  • 3,185
  • 1
  • 26
  • 17
  • Works, and I'd assume that it's more efficient than getting an InputStream just to see if the file exists. Nice. – David Snabel-Caunt Mar 01 '12 at 12:08
  • 5
    What if FILE_NAME = filename + path ? – Lou Morda Jul 27 '12 at 23:18
  • what do you mean? FILE_NAME should be a file path relative to the (unknown) private directory of your application. The fact that FILE_NAME contains subdirectories is not a problem for testing its existence; if you have to create that file, you can ensure the required subdirectories as usual in Java, [see the docs](http://developer.android.com/reference/java/io/File.html#mkdirs()) – lencinhaus Oct 16 '12 at 18:18
  • @lencinhaus how about this: File file = new File(filePath); if (file.exists()) since I have a URI file path already and dont want an extra step extracting the file name? Does this actually open the file compares to your way? – jerrytouille Apr 19 '13 at 05:56
  • This not work if you try access to file outside you right, for example '/system/bin/file' on non-root device – Tapa Save May 05 '14 at 13:10
  • This method raises exception `java.lang.IllegalArgumentException: File /data/data/your.package.name/file.html contains a path separator`. Use http://stackoverflow.com/a/16238330/2914140 instead. – CoolMind Jun 09 '16 at 12:31
26

The documentation says Context.openFileInput either returns an inputStream (file found) or throws a FileNotFoundException (not found)

http://developer.android.com/reference/android/content/Context.html#openFileInput(java.lang.String)

So it looks like the exception is your "test".

You could also try using standard

java.io.File file = new java.io.File(PATHTOYOURCONTEXT , FILE);
if (file.exists()) {
    FileInputStream fIn = new FileInputStream(file);
}

But that is not recommended. Context.openFileInput() and Context.openFileOutput() make sure you stay in your applications storage context on the device, and that all of your files get deleted when your app gets uninstalled.

rompetroll
  • 4,781
  • 2
  • 37
  • 50
5

With the standard java.io.File this is the function I have created, and works correctly:

private static final String APP_SD_PATH = "/Android/data/com.pkg.myPackage";
...
public boolean fileExistsInSD(String sFileName){
    String sFolder = Environment.getExternalStorageDirectory().toString() + 
            APP_SD_PATH + "/Myfolder";
    String sFile=sFolder+"/"+sFileName;
    java.io.File file = new java.io.File(sFile);
    return file.exists();
}
jnthnjns
  • 8,962
  • 4
  • 42
  • 65
molbalga
  • 101
  • 2
  • 4
  • Context.getExternalFilesDir() returns the same as Environment.getExternalStorageDirectory().toString() + APP_SD_PATH – riper Apr 03 '13 at 17:19
2

why dont you just catch the FileNotFound exception and take that as the file not being present.

Prashast
  • 5,645
  • 3
  • 30
  • 31
  • That's the way I actually do , but I was wondering if there is another way – rantravee May 07 '10 at 09:39
  • @rantravee: The way you are doing is to catch all exceptions. Besides being kinda sloppy, it also doesn't tell you why the exception occurred. If you catch just `FileNotFoundException`, you'll know when you catch it that it was thrown because the file doesn't exist (rather than the generic Exception that could mean something went wrong with some call somewhere in your try block or the stuff it calls, or the stuff that it calls calls, or....) – cHao May 28 '11 at 15:08
  • Generally it's best if exceptions are just that - exceptions. Check if the file exists or not, and if after creating it it some how still does not exist keep the try/catch as a fall back. – Ken Sep 30 '11 at 02:12
1

If you want to ensure a file exists (i.e. if it doesn't exist create a new one, if it does then don't erase it) then use File.createNewFile:

https://docs.oracle.com/javase/7/docs/api/java/io/File.html#createNewFile()

e.g.

{
        String pathName = <file path name>
        File file = new File (pathName);
        Uri pathURI = Uri.fromFile (file);
        boolean created;

        String mIOException = "";
        String mSecException = "";

        try
        {
            created = file.createNewFile();

            if (created)
            {
                ctxt.sendBroadcast (new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, pathURI));
            }
        }
        catch (IOException ioex)
        {
            mIOException = ioex.getMessage();
        }
        catch (SecurityException sex)
        {
            mSecException = sex.getMessage();
        }

}
Den-Jason
  • 2,395
  • 1
  • 22
  • 17
0

If you want to open a file in any case (i.e. if it doesn't exist create a new one, if it does append to the old one) you can use this, no testing necessary:

public static void write_custom_log(String message){
        File root = Environment.getExternalStorageDirectory();
        try{
            BufferedWriter fw = new BufferedWriter(new FileWriter(new File("/mnt/sdcard/tjb_tests/tjb_log_file.txt"),true));

            if (root.canWrite()){
                fw.write(message);
                fw.close();
                }
            } catch (IOException e) {
                Log.e("One", "Could not write file " + e.getMessage());
            }
    }
tjb
  • 11,480
  • 9
  • 70
  • 91
-2

My suggestion is to check length of the file. if file.length() returns 0 that means file doesn't exist.

Thiem Nguyen
  • 6,345
  • 7
  • 30
  • 50