44

I try to save a txt file in my folder, in internal storage, but I face the same problem every time:

"Source Not Found"

I write my code in different ways expressed here as follows but in all ways I have the same problem.

It is worth saying that I even add

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

in Manifest.xml that is not necessary for internal storage.

It is needless to say that I don't have any problem to save files in /data/data/package/files path, but when I add my folder in the files' root for example /data/data/package/files/myforlder/myfile.txt I face the "Source Not Found" problem.

Could you point me in right direction to solve this ?

The second question is that, for saving a file in an external folder in external storage.
(for example: sdCard or USB storage) is the scenario different or is it same ?

First Way:

OutputStreamWriter out;
try {
    File path=new File(getFilesDir(),"myfolder");
    File mypath=new File(path,"myfile.txt");
    if (!mypath.exists()) {
        out = new OutputStreamWriter(openFileOutput( mypath.getAbsolutePath() , MODE_PRIVATE));
        out.write("test");
        out.close();
    }                           
}

Second way:

OutputStreamWriter out;
try {
    ContextWrapper cw = new ContextWrapper(this);
    File path = cw.getDir("myfolder", Context.MODE_PRIVATE);
    if (!path.exists()) {
        path.createNewFile();
        path.mkdir();
    }
    File mypath=new File(path,"myfile.txt");
    if (!mypath.exists()) {
        out = new OutputStreamWriter(openFileOutput( mypath.getAbsolutePath() , MODE_PRIVATE));
        out.write("test");
        out.close();
    }
}

Third way:

File path=getFilesDir();
String mypath=path.toString() + "/myfolder";
OutputStreamWriter out;
try {
    File  f = new File(mypath , "/myfile.txt"   );
out = new OutputStreamWriter(openFileOutput(f.getPath(), MODE_PRIVATE));
     out.write("test");
     out.close();                   
     }

Fourth Way:

File path=getFilesDir();

OutputStreamWriter out;
    try {
    File f = new File(path.getPath() + "/myfolder/myfile.txt"   );
    out = new OutputStreamWriter(openFileOutput(f.getPath(), MODE_PRIVATE));
    out.write("test");
    out.close();                    
    }

Fifth way:

File path=getFilesDir();                
OutputStreamWriter out;
try {
    File f = new File(path.getCanonicalPath() + "/myfile.txt");
    out = new OutputStreamWriter(openFileOutput( f.getPath(), MODE_PRIVATE));
    out.write("test");
    out.close();                    
    }
phwd
  • 19,975
  • 5
  • 50
  • 78
ScorpionGroup
  • 469
  • 1
  • 6
  • 8
  • 1
    While writing your question select the code and press ctrl+k, this will autoindent and colorize your code, so that is much more readable. No one will want to read that code unindented and uncolored. – Yekmer Simsek Apr 23 '11 at 20:16

3 Answers3

65

First Way:

You didn't create the directory. Also, you are passing an absolute path to openFileOutput(), which is wrong.

Second way:

You created an empty file with the desired name, which then prevented you from creating the directory. Also, you are passing an absolute path to openFileOutput(), which is wrong.

Third way:

You didn't create the directory. Also, you are passing an absolute path to openFileOutput(), which is wrong.

Fourth Way:

You didn't create the directory. Also, you are passing an absolute path to openFileOutput(), which is wrong.

Fifth way:

You didn't create the directory. Also, you are passing an absolute path to openFileOutput(), which is wrong.

Correct way:

  1. Create a File for your desired directory (e.g., File path=new File(getFilesDir(),"myfolder");)
  2. Call mkdirs() on that File to create the directory if it does not exist
  3. Create a File for the output file (e.g., File mypath=new File(path,"myfile.txt");)
  4. Use standard Java I/O to write to that File (e.g., using new BufferedWriter(new FileWriter(mypath)))
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • is that file and folder created in internal memory or sdcard ? – Shoshi Dec 28 '12 at 15:31
  • @Shoshi: `getFilesDir()` represents internal storage. – CommonsWare Dec 28 '12 at 15:33
  • @CommonsWare And how to make it private? I don't want to access to that file via third apps. – Dr.jacky Aug 30 '16 at 13:16
  • 2
    @Mr.Hyde: `getFilesDir()` *is* private. No apps other than yours can access it. The exception is on rooted devices, where *nothing* is private. – CommonsWare Aug 30 '16 at 13:19
  • @CommonsWare Ok, But I can't install a APK from that path (/data/data/com.packagename.mainactivity/files/sample.apk) – Dr.jacky Aug 31 '16 at 09:49
  • 1
    @Mr.Hyde: Correct. You *can't* have the APK be private and be able to install it, because you are not the installer app, and the installer app needs rights to read the APK to be able to install it. Now, the right solution is to use something like `FileProvider` and give the installer app a `content` `Uri` with temporary permissions. Unfortunately, that only works for Android 7.0+, as earlier versions of Android do not support `content` `Uri` values for app installation. Your only option, prior to Android 7.0, is to have the APK on external storage during the install process. – CommonsWare Aug 31 '16 at 10:55
  • @CommonsWare How about installing apk via "pm install" command with busybox?! BTW, I'mworking on a AOSP. – Dr.jacky Aug 31 '16 at 11:30
  • 1
    @Mr.Hyde: AFAIK, `pm install` still requires that the installer app have read access to the APK. I have never tried `pm install` with a `content` `Uri` -- I have only ever used it with a filesystem path. If by "working on a AOSP", you mean that you are building a custom ROM, you could try enabling `content` scheme support in the installer. That will require adding `content` to the `` and perhaps changing how the installer app reads in the APK. You might run diffs between your copy and the 7.0 sources to see what changed to enable this. – CommonsWare Aug 31 '16 at 11:55
17

Save:

public boolean saveFile(Context context, String mytext){
    Log.i("TESTE", "SAVE");
    try {
        FileOutputStream fos = context.openFileOutput("file_name"+".txt",Context.MODE_PRIVATE);
        Writer out = new OutputStreamWriter(fos);
        out.write(mytext);
        out.close();
        return true;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

Load:

public String load(Context context){
    Log.i("TESTE", "FILE");
    try {
        FileInputStream fis = context.openFileInput("file_name"+".txt");
        BufferedReader r = new BufferedReader(new InputStreamReader(fis));
        String line= r.readLine();
        r.close();
        return line;
    } catch (IOException e) {
        e.printStackTrace();
        Log.i("TESTE", "FILE - false");
        return null;
    }
}
Beto Caldas
  • 2,198
  • 2
  • 23
  • 23
1

The answer of Mintir4 is fine, I would also do the following to load the file.

FileInputStream fis = myContext.openFileInput(fn);
BufferedReader r = new BufferedReader(new InputStreamReader(fis));
String s = "";

while ((s = r.readLine()) != null) {
    txt += s;
}

r.close();
Bob
  • 31
  • 4