I'm not able to understand these classes. I've been trying to create a new file in a new directory on my internal storage, put some text in it and then to read it out. This does not seem to work without the ContextWrapper. So I tried this:
public class DownloadActivity extends Activity {
...
class Download extends AsyncTask<String, Void, String>{
....
private void searchAndSave(String s) throws IOException {
....
ContextWrapper cw = new ContextWrapper(getBaseContext());
File folder = cw.getDir("folder", Context.MODE_PRIVATE);
File fileInFolder = new File(folder, "fileInFolder");
String string = "Hello world!";
FileOutputStream outputStream = openFileOutput("fileInFolder",
Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
File fl = new File(cw.getDir("folder", Context.MODE_PRIVATE)+"/fileInFolder");
FileInputStream fin = new FileInputStream(fl);
BufferedReader reader = new BufferedReader(
new InputStreamReader(fin));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
String result = sb.toString();
reader.close();
fin.close();
}
}
Creating the file does not work without the ContextWrapper. I've been reading a lot, but I still have problems to understand, what the Context and the Contextwrapper actually do and why I need them to create a file. Additionally in my code the creating of the FileInputStream does not work. When the program reaches
FileInputStream fin = new FileInputStream(fl);
I always get the error:
05-21 11:18:25.721: W/System.err(7344): java.io.FileNotFoundException:
/data/data/com.example.dice/app_folder/fileInFolder: open failed:
ENOENT (No such file or directory)
I really would appreciate some help with understanding and solving this problem.
UPDATE: I made a more spare Activity, maybe now it's easier to reconstruct the whole thing. (Should I have done this in a new answer, or is it okay to edit my first posting?) Even though I don't get an error message when trying to create a file, is doesn't seem to work. Here I try reading the "Hello world" string, but I get a FileNotFoundException (EISDIR). Just for you to know :)
public class FolderActivity extends Activity {
public final static String TAG = "FolderActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_folder);
Button button = (Button) findViewById(R.id.button_folder);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
folder();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void folder() throws IOException{
Log.d(TAG, "folder");
ContextWrapper cw = new ContextWrapper(getBaseContext());
Log.d(TAG, "cw = new ContextWrapper");
File folder = cw.getDir("folder", Context.MODE_PRIVATE);
Log.d(TAG, "folder = cw.getDir");
File fileInFolder = new File(folder, "fileInFolder");
Log.d(TAG, "fileInFolder = new File");
/*Log.d(TAG,
"fileInFolder.getAbsolutePath()"
+ fileInFolder.getAbsolutePath());*/
String string = "Hello world!";
// Aksioms suggestion
if (!fileInFolder.exists() && !fileInFolder.mkdirs()) {
Log.e("file", "Couldn't create file " + fileInFolder);
} else { Log.d(TAG, "file created"); }
FileOutputStream outputStream = openFileOutput("fileInFolder",
Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
Log.d(TAG,
"fileInFolder.getAbsolutePath()"
+ fileInFolder.getAbsolutePath());
String s = fileInFolder.getAbsolutePath();
try {
getStringFromFile(s);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getStringFromFile (String filePath) throws Exception {
File fl = new File(filePath);
FileInputStream fin = new FileInputStream(fl);
String ret = convertStreamToString(fin);
//Make sure you close all streams.
fin.close();
return ret;
}
public static String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}
}
You are trying to open a file which does not exists. Make sure that you check and create the file if it does not exsist:
if (!fl.exists() && !fl.mkdirs()) {
Log.e("file", "Couldn't create file " + fl);
}
EDIT:
Yes the getDir creats the folder if it is not created.
File folder = cw.getDir("folder", Context.MODE_PRIVATE);
But the problem is here
File fileInFolder = new File(folder, "fileInFolder");
String string = "Hello world!";
FileOutputStream outputStream = openFileOutput("fileInFolder",
Context.MODE_PRIVATE);
In here you try to open a file that does not exsist, you just constructed a new file named fileInFolder, but you actually do not have that folder yet.
Try to use the code that I wrote at the first place, before the openFileOutput("fileInFolder", Context.MODE_PRIVATE); :
if (!fileInFolder.exists() && !fileInFolder.mkdirs()) {
Log.e("file", "Couldn't create file " + fileInFolder);
}
Try this and tell me how it goes.
EDIT 2:
OK I found the problem it was so obvious. The mistake was that we created the fileInFolder as a directory, and you can not write anything there :D
What we should have done is this:
Remove my code for creating the fileInFolder.
if (!fileInFolder .exists() && !fileInFolder .mkdirs()) {
Log.e("file", "Couldn't create file " + fileInFolder );
} else {
Log.d(TAG, "file created");
}
we do not need to create it because we will use it as a file. So the change I have made in your code is this:
FileOutputStream outputStream = new FileOutputStream(fileInFolder);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outputStream));
out.write(string);
out.close();
Add this between the line String string = "Hello world!"; and the first Log.d... This is the correct way to write in a file.
The whole code:
public class MainActivity extends Activity {
public final static String TAG = "FolderActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button button = (Button) findViewById(R.id.button_folder);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try {
folder();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
private void folder() throws IOException {
Log.d(TAG, "folder");
ContextWrapper cw = new ContextWrapper(getBaseContext());
Log.d(TAG, "cw = new ContextWrapper");
File folder = cw.getDir("folder", Context.MODE_PRIVATE);
Log.d(TAG, "folder = cw.getDir");
File fileInFolder = new File(folder, "fileInFolder");
Log.d(TAG, "fileInFolder = new File");
/*
* Log.d(TAG, "fileInFolder.getAbsolutePath()" +
* fileInFolder.getAbsolutePath());
*/
String string = "Hello world!";
FileOutputStream outputStream = new FileOutputStream(fileInFolder);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(outputStream));
out.write(string);
out.close();
Log.d(TAG,
"fileInFolder.getAbsolutePath()"
+ fileInFolder.getAbsolutePath());
String s = fileInFolder.getAbsolutePath();
try {
getStringFromFile(s);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getStringFromFile(String filePath) throws Exception {
File fl = new File(filePath);
FileInputStream fin = new FileInputStream(fl);
String ret = convertStreamToString(fin);
// Make sure you close all streams.
fin.close();
return ret;
}
public static String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
reader.close();
return sb.toString();
}}
Check if you have this permission in your manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I hope everything is clear now.