Creating temporary files in Android - android

What's the best way to create a temporary file in Android?
Can File.createTempFile be used? The documentation is very vague about it.
In particular, it's not clear when temporary files created with File.createTempFile are deleted, if ever.

This is what I typically do:
File outputDir = context.getCacheDir(); // context being the Activity pointer
File outputFile = File.createTempFile("prefix", ".extension", outputDir);
As for their deletion, I am not complete sure either. Since I use this in my implementation of a cache, I manually delete the oldest files till the cache directory size comes down to my preset value.

Best practices on internal and external temporary files:
Internal Cache
If you'd like to cache some data, rather than store it persistently,
you should use getCacheDir() to open a File that represents the
internal directory where your application should save temporary cache
files.
When the device is low on internal storage space, Android may delete
these cache files to recover space. However, you should not rely on
the system to clean up these files for you. You should always maintain
the cache files yourself and stay within a reasonable limit of space
consumed, such as 1MB. When the user uninstalls your application,
these files are removed.
External Cache
To open a File that represents the external storage directory where
you should save cache files, call getExternalCacheDir(). If the user
uninstalls your application, these files will be automatically
deleted.
Similar to ContextCompat.getExternalFilesDirs(), mentioned above,
you can also access a cache directory on a secondary external storage
(if available) by calling ContextCompat.getExternalCacheDirs().
Tip: To preserve file space and maintain your app's performance, it's
important that you carefully manage your cache files and remove those
that aren't needed anymore throughout your app's lifecycle.

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.

You can use the cache dir using context.getCacheDir().
File temp=File.createTempFile("prefix","suffix",context.getCacheDir());

You can use the File.deleteOnExit() method
https://developer.android.com/reference/java/io/File.html#deleteOnExit()
It is referenced here https://developer.android.com/reference/java/io/File.html#createTempFile(java.lang.String, java.lang.String, java.io.File)

Do it in simple. According to documentation
https://developer.android.com/training/data-storage/files
String imageName = "IMG_" + String.valueOf(System.currentTimeMillis()) +".jpg";
picFile = new File(ProfileActivity.this.getCacheDir(),imageName);
and delete it after usage
picFile.delete()

Related

Android: How to move a file to another folder using SAF(storage access framework), and how to list file with display name?

As Google is trying to enforcing apps to use SAF for storage access, I am trying to adapt my app to use SAF replacing java file io apis.
I have spent many hours study the SAF APIs (mainly DocumentFile and DocumentContract classes) but still have some difficulties.
First one is how to move a file to another directory? DocumentFile does have a method to rename a file, but it is just the display name of the file. How can I move a file to another folder, if it is a huge file which I don't want to copy it. Assume src and dst are on the same partition.
Second question is how to list child files efficiently. I checked the source code and found that DocumentFile.listFiles() impl only queries the child files with single projection [ID]. And later when I want to display the files in a list view with their names, the call to DocumentFile.getName() will trigger another query via content resolver for each file again. This is a huge impact on the performance of the code. Especially when I try to sort an array of DocumentFile by their names, 30+ files will cost 600+ms, which is far beyond the acceptable. I doubt whether I am using the correct API set. Could anyone point out a better way to list files with names (and other properties)?
Simple Storage is a library that simplify SAF across API levels. Suppose that you want to move a MP4 file from directory Video in external storage into directory Others in SD card. Let's assume that AAAA-BBBB as SD card's storage ID:
val source = DocumentFileCompat.fromSimplePath(context, basePath = "Video/Infinity War.mp4")
val targetFolder = DocumentFileCompat.fromSimplePath(context, storageId = "AAAA-BBBB", basePath = "Others")
// To move file:
source.moveFileTo(context, targetFolder, callback)
// To copy file:
source.copyFileTo(context, targetFolder, callback)

Android Get Application Start Up Path

In C# there are Application.StartUpPath or Application.AppDataPath global methods to get a path where I would store Application Settings.
I tried static String fName = System.getProperty("user.dir") + "SatCli.conf";
"/SatCli.conf" - is the resulted fName
then I call
BufferedOutputStream oustream = new BufferedOutputStream(new
FileOutputStream(fName, false));
and I am getting the common exception
"/SatCli.conf: open failed: EROFS (Read-only file system)"
Well, I've been writing apps under Unix and I understand maybe the file name is refering to internal memory.. in other words to the root part of system file system.
Or maybe not.. maybe it refers to the App Folder?
Anyway, what I would like to get is the correct method to get the right folder to store the settings data.
Also, what is important, I need it before any context is built, when static fields are initializing.
Thank you for any relevant hint and help.
what I would like to get is the correct method to get the right folder to store the settings data.
For arbitrary files, call getFilesDir() on a Context (e.g., Activity). This gives you a File object representing a private directory where your app can read and write.
FWIW, Android's standard way of storing settings that you collect from the user is SharedPreferences, so you can take advantage of PreferenceFragment for the UI.

what does it mean to delete a file on android

Naturally I thought to delete a file means to remove it from existence. So when I do
File file = new File(absPath);
....//add content
file.delete();
I expect that no further operation can be executed on file or it would throw an exception. But how come I can still add content to the file such as shown here Android saving Bitmap to SD card. So how do I delete a file so that it is completely gone? So that when someone go look through file manager, the file is no longer there? I am not in a position to test this now, so I was hoping for authoritative reference.
how come I can still add content to the file such as shown here Android saving Bitmap to SD card.
That code creates a new file after deleting the old one.
So how do I delete a file so that it is completely gone? So that when someone go look through file manager, the file is no longer there?
Call delete() on a File object that points to the file. Then, do not use that same File object to write to the file again, thereby creating a new file, as the code that you link to does.

Android file atomic operation

I need to read some data from file in internal storage, then remove and rewrite file with new data. What is the best way to do it(safest method for data)?
I'd first rename the original file (append something like .orig), then read it, write the new file and when all that's successful, remove the renamed original file. This ensures the most that no data gets lost.

Creating directory in application package on internal storage

Is it possible for android application to create several directories in internal storage for storing there different kinds of files? I need this capability, because I'll need to delete a kind of files at definite time moment in my application.
When I try to use standard Context method openFileOutput() and send to it filename with "/" symbol I get IllegalArgumentException.
Tell me please what classes and methods could allow me such functionality?
Use Context.getDir(String name, int mode) method to create or access directories in internal storage. Quote from docs:
Retrieve, creating if needed, a new directory in which the application can place its own custom data files. You can use the returned File object to create and access files in this directory. Note that files created through a File object will only be accessible by your own application; you can only set the mode of the entire directory, not of individual files.
UPD Example:
File mydir = context.getDir("mydir", Context.MODE_PRIVATE); //Creating an internal dir;
File fileWithinMyDir = new File(mydir, "myfile"); //Getting a file within the dir.
FileOutputStream out = new FileOutputStream(fileWithinMyDir); //Use the stream as usual to write into the file.

Categories

Resources