Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create nested folders and file in Context.MODE_PRIVATE?

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:-

  1. How do I create nested file structure using openFileOutput() method under MODE_PRIVATE(if it's possible)?

  2. 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?

like image 448
Abhinav Avatar asked Mar 21 '23 20:03

Abhinav


2 Answers

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);
like image 136
Pankaj Kumar Avatar answered Apr 07 '23 12:04

Pankaj Kumar


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.

like image 32
Ali Avatar answered Apr 07 '23 11:04

Ali