27

I want to save a file on internal storage into a specific folder. My code is:

File mediaDir = new File("media");
if (!mediaDir.exists()){
   mediaDir.createNewFile();
   mediaDir.mkdir();

}
File f = new File(getLocalPath());
f.createNewFile();
FileOutputStream fos = new FileOutputStream(f);
fos.write(data);
fos.close();

getLocalPath returns /data/data/myPackage/files/media/qmhUZU.jpg but when I want to create the media folder I'm getting the exception "java.io.IOException: Read-only file system". Any ideas how to write my files on internal phone storage in in folder media? Thanks.

Agna JirKon Rx
  • 2,321
  • 2
  • 29
  • 44
Buda Gavril
  • 21,409
  • 40
  • 127
  • 196

5 Answers5

23

You should use ContextWrapper like this:

ContextWrapper cw = new ContextWrapper(context);
File directory = cw.getDir("media", Context.MODE_PRIVATE);

As always, refer to documentation, ContextWrapper has a lot to offer.

Audrius
  • 2,836
  • 1
  • 26
  • 35
  • I didn't understand one thing, how is it different from calling the same method of the original context? – Malcolm May 24 '11 at 10:30
  • 1
    ContextWrapper is just a proxy to the original context. The benefit here is that you can subclass ContextWrapper to achieve some custom behavior, so that say getDir() actually returns some other (non-standard) directory. You are right that one can use Context directly tho'. – Audrius May 24 '11 at 12:53
2

You should create the media dir appended to what getLocalPath() returns.

Lucas S.
  • 13,391
  • 8
  • 46
  • 46
2

I was getting the same exact error as well. Here is the fix. When you are specifying where to write to, Android will automatically resolve your path into either /data/ or /mnt/sdcard/. Let me explain.

If you execute the following statement:

File resolveMe = new File("/data/myPackage/files/media/qmhUZU.jpg");
resolveMe.createNewFile();

It will resolve the path to the root /data/ somewhere higher up in Android.

I figured this out, because after I executed the following code, it was placed automatically in the root /mnt/ without me translating anything on my own.

File resolveMeSDCard = new File("/sdcard/myPackage/files/media/qmhUZU.jpg");
resolveMeSDCard.createNewFile();

A quick fix would be to change your following code:

File f = new File(getLocalPath().replace("/data/data/", "/"));

Hope this helps

Tyler
  • 19,113
  • 19
  • 94
  • 151
  • 3
    This is replacing a very bad idea with a slightly less bad idea, but still unwise - ordinarily application should just not be assuming absolute paths, but rather discovering the applicable ones at runtime using the provided APIs. – Chris Stratton Oct 29 '13 at 15:09
0

Write a file

When saving a file to internal storage, you can acquire the appropriate directory as a File by calling one of two methods:

getFilesDir()

      Returns a File representing an internal directory for your app.

getCacheDir()

     Returns a File representing an internal directory for your 
     app's temporary cache files.
     Be sure to delete each file once it is no longer needed and implement a reasonable 
     size limit for the amount of memory you use at any given time, such as 1MB.

Caution: If the system runs low on storage, it may delete your cache files without warning.

Denys Yurchenko
  • 333
  • 5
  • 10
-3

Hi try this it will create directory + file inside it

File mediaDir = new File("/sdcard/download/media");
if (!mediaDir.exists()){
    mediaDir.mkdir();
}

File resolveMeSDCard = new File("/sdcard/download/media/hello_file.txt");
resolveMeSDCard.createNewFile();
FileOutputStream fos = new FileOutputStream(resolveMeSDCard);
fos.write(string.getBytes());
fos.close();

System.out.println("Your file has been written");  
Tyler
  • 19,113
  • 19
  • 94
  • 151