59

In my app I added the possibility to add and save pictures for everyday day, represented by a Fragment.

In order to save the picture on the SD card, I currently use the function File.createTempFile:

File imageFile = File.createTempFile(imageFileName, MyApplication.JPEG_FILE_SUFFIX, MyApplication.getAlbumDir());

I actually also tried with the standard way:

File imageFile = new File(MyApplication.getAlbumDir(), imageFileName + MyApplication.JPEG_FILE_SUFFIX);

Both are working, but in my case the first one is better than the second one because the function createTempFile adds a long random number at the end of the file name making it unique.

To give you an example, here is what I get with both methods:

With createTempFile: IMG_2013-06-18_-1961144729.jpg

With new File: IMG_2013-06-18_.jpg

Finally my question is, is it safe to keep using createTempFile to save my pictures or do I have to use the standard way and add some code to generate a unique file name? Should it only be used for temporary files?

I reviewed the documentation about the function but I did not find anything about the possible consequences of using it instead of new File.

Thank you

Yoann Hercouet
  • 17,272
  • 4
  • 56
  • 80

3 Answers3

32

Sounds like your app is creating files, so you need to guarantee unique filenames. You could keep some kind of counter within your app (saved to preferences or DB) and use that. Then you could create shorter/more controlled names, and control uniqueness yourself. Or you can use createTempFile(), which will guarantee you get a unique filename (but you only get partial control of the filename). Sounds like you prefer createTempFile(), so there's no reason not to continue using it if you are happy with the filenames it generates. There's no down side other than not having full control over the filename format.

user1676075
  • 2,958
  • 1
  • 17
  • 25
  • 1
    Yes, `createTempFile` is giving me the results I want, but my question actually is: is it safe to keep using this function while actually it seems to be meant for temporary file creations only. – Yoann Hercouet Jun 17 '13 at 15:07
  • 3
    Yes, it is safe. Again, only downside/difference is that you don't have complete control of the filename. – user1676075 Jun 17 '13 at 15:56
  • So createTempFile() doesn't actually create *temp* files – pete Aug 11 '20 at 06:02
30

1. Create file with random name

File file = File.createTempFile(String prefix, String suffix, File parent)
  • Actually create the file on disk and returns the file object
  • Create a file name in this format: prefix + random number + suffix
  • Useful when you need create temporary file on disk

2. Create file with exact name

File file = new File(File parent, String child);
file.createNewFile();
  • Actually create the file on disk and returns true if file get created successfully

  • File name will exactly as pass to child parameter

  • Useful when you need create permanent file on disk

3. Create only file object (in memory)

File file = new File(File parent, String child);
// doesn't create the file on disk until calling createNewFile() method
  • Only create the in memory and not actually on disk
  • Useful when you need just create file object (e.g just to pass it as parameter)

parent parameter can be one of these:

  1. App private directories

    • context.getCacheDir()
    • context.getExternalCacheDir()
    • and ... (full list can be found here)
  2. Public directories

    • Environment.getExternalStorageDirectory()
    • Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES)
    • and ... (full list can be found here)
Behzad Bahmanyar
  • 5,696
  • 4
  • 29
  • 38
  • 1
    Thanks for 3 (file as a parameter). getExternalStoragePublicDirectory is now deprecated. See https://commonsware.com/blog/2019/04/22/death-external-storage-more-story.html. – CoolMind Jul 15 '19 at 08:37
25

For temporary internal files their are 2 options

1.

File file; 
file = File.createTempFile(filename, null, this.getCacheDir());

2.

File file
file = new File(this.getCacheDir(), filename);

Both options adds files in the applications cache directory and thus can be cleared to make space as required but option 1 will add a random number on the end of the filename to keep files unique. It will also add a file extension which is .tmp by default but it can be set to anything via the use of the 2nd parameter. The use of the random number means despite specifying a filename it doesn't stay the same as the number is added along with the suffix/file extension (.tmp by default) e.g you specify your filename as internal_file and comes out as internal_file1456345.tmp . Whereas you can specify the extension you can't specify the number that is added. You can however find the filename it generates via file.getName(); but you would need to store it somewhere so you can use it whenever you wanted for example to delete or read the file. Therefore for this reason I prefer the 2nd option as the filename you specify is the filename that is created.

AdrenalineJunky
  • 751
  • 10
  • 15
  • 2
    Please note, creating temp files in cache will not work for [certain activities](http://stackoverflow.com/questions/18711525/camera-not-working-saving-when-using-cache-uri-as-mediastore-extra-output) – Atul May 14 '16 at 08:06
  • @Atul, well it works (at least now), you just need to use FileProvider. – dragi Dec 08 '17 at 08:36