How to create files hierarchy in Androids '/data/data/pkg/files' directory?
Asked Answered
H

5

9

I try to create 'foo/bar.txt' in Android's /data/data/pkg/files directory.

It seems to be a contradiction in docs:

To write to a file, call Context.openFileOutput() with the name and path.

http://developer.android.com/guide/topics/data/data-storage.html#files

The name of the file to open; can not contain path separators.

http://developer.android.com/reference/android/content/Context.html#openFileOutput(java.lang.String,%20int)

And when I call

this.openFileOutput("foo/bar.txt", Context.MODE_PRIVATE);

exception is thrown:

java.lang.IllegalArgumentException: File foo/bar.txt contains a path separator

So how do I create file in subfolder?

Hyaline answered 11/12, 2009 at 16:26 Comment(0)
R
13

It does appear you've come across a documentation issue. Things don't look any better if you dig into the source code for ApplicationContext.java. Inside of openFileOutput():

File f = makeFilename(getFilesDir(), name);

getFilesDir() always returns the directory "files". And makeFilename()?

private File makeFilename(File base, String name) {
    if (name.indexOf(File.separatorChar) < 0) {
        return new File(base, name);
    }
    throw new IllegalArgumentException(
        "File " + name + " contains a path separator");
}

So by using openFileOutput() you won't be able to control the containing directory; it'll always end up in the "files" directory.

There is, however, nothing stopping you from creating files on your own in your package directory, using File and FileUtils. It just means you'll miss out on the conveniences that using openFileOutput() gives you (such as automatically setting permissions).

Returnable answered 11/12, 2009 at 16:45 Comment(1)
the FileUtils are not available to the Java apps using the SDK. Do you add it to your project libraries? And where do you download the library from?Palmette
O
9

You can add files with path in private directory like that

String path = this.getApplicationContext().getFilesDir() + "/testDir/";
File file = new File(path);
file.mkdirs();
path += "testlab.txt";
OutputStream myOutput;
try {
myOutput = new BufferedOutputStream(new FileOutputStream(path,true));
write(myOutput, new String("TEST").getBytes());
myOutput.flush();
myOutput.close();
} catch (FileNotFoundException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
Orvas answered 27/7, 2011 at 13:23 Comment(2)
getFilesDir() returns a File, so concatenating it with a String won't work.Hissing
hi Tad ! File class override toString() method. So concatenate it with a string will call toString() automaticallyOrvas
A
8

Use getFilesDir() to get a File at the root of your package's files/ directory.

Agathy answered 11/12, 2009 at 17:30 Comment(2)
I tried this but a FileOutputStream with that parameter fails with: /data/data/com.example.myapp/files/subfolder/foo.txt: open failed: EACCES (Permission denied). Any other things I have to take into account?Tamekia
@avalancha: Well, you have to create the subfolder/ directory, using mkdir() on a File object pointing there.Agathy
I
5

To write to a file in a subfolder of internal storage you will need to create the file (and subfolder if not already there) first, then create the FileOutputStream object.

Here is the method I used

    private void WriteToFileInSubfolder(Context context){
    String data = "12345";
    String subfolder = "sub";
    String filename = "file.txt";

    //Test if subfolder exists and if not create
    File folder = new File(context.getFilesDir() + File.separator + subfolder);
    if(!folder.exists()){
        folder.mkdir();
    }


    File file = new File(context.getFilesDir() + File.separator 
                         + subfolder + File.separator + filename);
    FileOutputStream outstream;

    try{
        if(!file.exists()){
            file.createNewFile();
        }

        //commented line throws an exception if filename contains a path separator
        //outstream = context.openFileOutput(filename, Context.MODE_PRIVATE);
        outstream = new FileOutputStream(file);
        outstream.write(data.getBytes());
        outstream.close();

    }catch(IOException e){
        e.printStackTrace();
    }
}
Isbella answered 15/5, 2014 at 1:10 Comment(0)
U
0

Assuming the original post sought how to both create a subdirectory in the files area and write a file in it, this might be new in the docs:

public abstract File getDir (String name, int mode)

Since: API Level 1

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.

Umbria answered 19/3, 2012 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.