I have a requirement where files and folders are required to be written in nested structure using Context.MODE_PRIVATE
.
I found that we can create file using openFileOutput(FILENAME, Context.MODE_PRIVATE);
and was able to create files using this method.But later on I found that using this method I can not create a nested file structure i.e for
openFileOutput("foo/myText.txt", Context.MODE_PRIVATE);
exception is thrown:
java.lang.IllegalArgumentException: File foo/myText.txt contains a path separator
May be because it expects only a fileName & not a filepath
and also documentation says
Open a private file associated with this Context's application package for writing.
Then I found that getFilesDir()
returns Context's application package where I can create files using the normal Java File I/O.But I don't know the permissions under which it is created i.e whether it is MODE_APPEND
,MODE_PRIVATE
,MODE_WORLD_READABLE
or MODE_WORLD_WRITEABLE
.
So, I have following questions:-
How do I create nested file structure using openFileOutput() method under MODE_PRIVATE(if it's possible)?
If openFileOutput() is not applicable to create a nested structure,then is it safe to use getFilesDir()
and Java File I/O combination for my requirement? What is the permission for the files created using this way?
You need to create foo
directory first then create file inside that dir.
Use getDir(String name, int mode) to create directory into internal memory. The method 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.
For example
// Create directory into internal memory;
File mydir = context.getDir("mydir", Context.MODE_PRIVATE);
// Get a file myfile within the dir mydir.
File fileWithinMyDir = new File(mydir, "myfile");
// Use the stream as usual to write into the file.
FileOutputStream out = new FileOutputStream(fileWithinMyDir);
So your need to write your code as
// Create foo directory into internal memory;
File mydir = getDir("foo", Context.MODE_PRIVATE);
// Get a file myText.txt within the dir foo.
File fileWithinMyDir = new File(mydir, "myText.txt");
// Use the stream as usual to write into the file.
try {
FileOutputStream out = new FileOutputStream(fileWithinMyDir);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
to create foo/myText.txt into internal storage.
For nested directories, you should use normal java method. Like
new File(parentDir, "childDir").mkdir();
So updated example should be
// Create directory into internal memory;
File mydir = getDir("mydir", Context.MODE_PRIVATE);
// Create sub-directory mysubdir
File mySubDir = new File(mydir, "mysubdir");
mySubDir.mkdir();
// Get a file myfile within the dir mySubDir.
File fileWithinMyDir = new File(mySubDir, "myfile");
// Use the stream as usual to write into the file.
FileOutputStream out = new FileOutputStream(fileWithinMyDir);
public OutputStream openFile(String absolutePath) throws FileNotFoundException {
File file = new File(absolutePath);
new File(file.getParent()).mkdirs();
return new FileOutputStream(absolutePath);
}
public OutputStream openInternalFile(String relativePath) throws FileNotFoundException {
String rootPath = this.getFilesDir().getPath();
File file = new File(rootPath, relativePath);
return openFile(file.getAbsolutePath());
}
This is what I came up which covers your use case. You can either pass the absolutePath
or relativePath
. behind the scene it does create a nested folders inside internal storage and returns back an OutputStream
which you can start write into it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With