It's perfectly described here how to do it, the only problem: He doesnt know the function openFileOutput();
private void saveSettingsFile() {
String FILENAME = "settings";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE); //openFileOutput underlined red
try {
fos.write(string.getBytes());
fos.close();
} catch (IOException e) {
Log.e("Controller", e.getMessage() + e.getLocalizedMessage() + e.getCause());
}
}
Those are the relevant packages I imported:
import java.io.FileOutputStream;
import java.io.IOException;
import android.content.Context;
Have a look at this example of using a FileOutputStrem from the Examples on dev.android.com. It should give you an idea of how to use it correctly.
Class within which this method is declared, is defined as "Static". thats why it is throwing error. Remove static from the class definition and bingo...
Just add a "try catch" block and put them in between this.
Like this:
private void saveSettingsFile(String FILENAME, String data) {
FileOutputStream fos;
try {
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} // openFileOutput underlined red
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When there is red line under the line.. First check that the line is under the full sentense or only right side of the sentense .(i.e after equal sign).
If it covers the whole line, then it has to fix some bugs..
Or if it under only the right side of the sentense ...Then it must wants some exception handling things.
If you don't know what type of exception it may generate...
Dont fear , just write all the code in a try block( try{ } ) and then add a catch and pass a Exception object inside catch .. Now its fine..
Like this :
try
{
...........your code
......
}
catch(Exception e)
{
e.printstacktrace();
}
Now all are fine.
Thank you
openFileOutput is a method of Context object. And don't forget to add finally clause to close the stream. Bellow is an example (a bit clumsy because of Java 6 because of Android).
String data = "Hello";
FileOutputStream fos = null;
try {
fos = mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(data.getBytes(Charset.defaultCharset()));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
mContext variable should be defined somewhere above and initialized like mContext = getApplicationContext() if you are inside of an activity
Related
Honestly, I've searched a lot do this task so I ended up trying various methods but nothing worked until I ended up on this code. It works for me perfectly like it should, so I do not want to change my code.
The help I need is to put this code in a such a way that it begins to read a file, but if it the file doesn't exist then it will create a new file.
Code for saving data:
String data = sharedData.getText().toString();
try {
fos = openFileOutput(FILENAME, MODE_PRIVATE);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Code for loading data:
FileInputStream fis = null;
String collected = null;
try {
fis = openFileInput(FILENAME);
byte[] dataArray = new byte [fis.available()];
while (fis.read(dataArray) != -1){
collected = new String(dataArray);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So If I add the saving data code in to the "FileNotFoundException" catch of the loading data part then could I achieve what I want?
Add
File file = new File(FILENAME);
if(!file.exists())
{
file.createNewFile()
// write code for saving data to the file
}
above
fis = openFileInput(FILENAME);
This will check if there exists a File for the given FILENAME and if it doesn't it will create a new one.
If you're working on Android, why don't you use the API's solution for saving files?
Quoting:
String filename = "myfile";
String string = "Hello world!";
FileOutputStream outputStream;
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(string.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
You should really read the whole document, they explain pretty well the basic ways of creating or accessing files, you can also check the different ways of storing data.
But regarding your original question:
So If I add the saving data code in to the "FileNotFoundException"
catch of the loading data part then could I achieve what I want?
Yes, you could achieve it.
Try this one:
public static void readData() throws IOException
{
File file = new File(path, filename);
if (!file.isFile() && !file.createNewFile()){
throw new IOException("Error creating new file: " + file.getAbsolutePath());
}
BufferedReader r = new BufferedReader(new FileReader(file));
try {
// ...
// read data
// ...
}finally{
r.close();
}
}
Ref: Java read a file, if it doesn't exist create it
Short way to reproduce the problem in my real project. Environment: Android SDK 1.16, Eclipse 4.2.0, Windows. Create default Android application and add the following code to MainActivity.java:
private void Save1(boolean externalStorage)
{
String s = "12345";
File file;
FileOutputStream fos = null;
if ( externalStorage )
{
try
{
file = new File(getExternalFilesDir(null), "log");
fos = new FileOutputStream(file); // Resource leak: 'fos' is never closed
}
catch(FileNotFoundException e)
{
return;
}
}
else
{
try
{
fos = openFileOutput("log", Context.MODE_PRIVATE);
}
catch(FileNotFoundException e)
{
return;
}
}
try
{
fos.write(s.getBytes());
fos.close();
}
catch(IOException e)
{
return;
}
}
private void Save2(boolean externalStorage)
{
String s = "12345";
File file;
FileOutputStream fos = null;
try
{
file = new File(getExternalFilesDir(null), "log");
fos = new FileOutputStream(file); // OK
}
catch(FileNotFoundException e)
{
return;
}
try
{
fos.write(s.getBytes());
fos.close();
}
catch(IOException e)
{
return;
}
}
Line fos = new FileOutputStream(file) in Save1 function, warning: Resource leak: 'fos' is never closed
The same line in Save2 function: no warnings.
Please don't send untested answers, the problem is not so simple as it looks. Adding fos.close() to different parts of the function doesn't help.
It also go away if i add an finally block to the try in the if block like this:
if (externalStorage) {
try {
fos = new FileOutputStream(new File(getExternalFilesDir(null),
"log"));
} catch (FileNotFoundException e) {
return;
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
try {
fos = openFileOutput("log", Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
return;
}
}
It is getting interesting...
So my guess would be, So if you are opening an Stream in a try block and catch block has an return statement then there should be a finally block that close the stream.
Something like that..
A tried the same code in a simple java project in eclipse and still got the warning. So it looks like is not related to lint or android. It looks like the eclipse compiler issue. Following is the code, I had to create a dummy openFileOutput() method since it is not available n java:
private void Save1(boolean externalStorage) {
String s = "12345";
FileOutputStream fos = null;
if (externalStorage) {
try {
fos = new FileOutputStream(new File("c://", "log"));
} catch (FileNotFoundException e) {
return;
}
} else {
try {
fos = openFileOutput("log", -1);
} catch (FileNotFoundException e) {
return;
}
}
try {
fos.write(s.getBytes());
fos.close();
} catch (IOException e) {
return;
}
}
/**
* #param string
* #param i
* #return
*/
private FileOutputStream openFileOutput(String string, int i)
throws FileNotFoundException {
return null;
}
This isn't an answer, but added here for clarity to the OP and other readers rather than a comment.
I've tested this in IDEA 11.2 API 15 using the current versions of the platform tool chain (Rev 14 Oct 2012) and there is no lint warning, compile error or runtime error. I forced the method to go through each path by creating exceptions and setting useExternalStorage both true and false.
My guess is this is a lint/compile error in your tool chain or possibly Eclipse (although unlikely, does Eclipse itself do any checking like this?).
[EDIT]
Just a thought, (and I would test but I've forgotten how to use Eclipse) but FileInputStream(file) might throw a SecurityException which would be thrown to somewhere up in your call stack. What happens if you catch it?
[EDIT]
This is the closest warning I get, and not at all relevant. I'm convinced the warning is not down to you.
In case of an Exception, fos wont be closed. Adding a finally to the try-catch would solve this issue.
try
{
fos = openFileOutput("log", Context.MODE_PRIVATE);
}
catch(FileNotFoundException e)
{
return;
}
//add this:
finally {
if (fos != null) {
fos.close();
}
}
I am able to write and then read a text file in the SAME activity, but I am unable to read a text file after writing to it from another Activity.
Ex: Activity A creates and writes to a text file. Activity B reads that text file.
I use this code to write to the text file in Activity A:
FileOutputStream fos = null;
OutputStreamWriter osw = null;
try
{
fos = openFileOutput("user_info.txt", Context.MODE_WORLD_WRITEABLE);
osw = new OutputStreamWriter(fos);
osw.write("text here");
osw.close();
fos.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And then I use this code to try and read the same text file created by Activity A, but I get a FileNotFoundException:
try
{
FileInputStream fis = openFileInput("user_info.txt");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader buff = new BufferedReader(isr);
String line;
while((line = buff.readLine()) != null)
{
Toast.makeText(this, line, Toast.LENGTH_LONG).show();
}
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Does anyone know why I am getting the FileNotFoundException?
Is it a path issue?
Don't really know how is built your application, but, the error you get does seem like a path issue, are you sure both Activities are in the same folder ?
If not, you'll need to set either an abolute path (like : "/home/user/text.txt") for the text file or a relative path (like : "../text.txt").
If you're not sure, try to print the current path for the Activity using some command like
new File(".").getAbsolutePath();
And, although I can't say I'm expert with Android, are you sure you need the Context.MODE_WORLD_WRITEABLE for your file ? If no other application than yours is reading or writing from/to it, it should not be necessary, right ?
it is surealy a path issue.
you can write like this
fpath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+"yourdirectory";
File custdir=new File(fpath);
if(!custdir.exists())
{
custdir.mkdirs();
}
File savedir=new File(custdir.getAbsolutePath());
File file = new File(savedir, filename);
if(file.exists())
{
file.delete();
}
FileOutputStream fos;
byte[] data = texttosave.getBytes();
try {
fos = new FileOutputStream(file);
fos.write(data);
fos.flush();
fos.close();
Toast.makeText(getBaseContext(), "File Saved", Toast.LENGTH_LONG).show();
finish();
} catch (FileNotFoundException e) {
Toast.makeText(getBaseContext(), "Error File Not Found", Toast.LENGTH_LONG).show();
Log.e("fnf", ""+e.getMessage());
// handle exception
} catch (IOException e) {
// handle exception
Toast.makeText(getBaseContext(), "Error IO Exception", Toast.LENGTH_LONG).show();
}
and you can read like
String locatefile=Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+"yourdirectory"+"/filename";
try {
br=new BufferedReader(new FileReader(locatefile));
while((text=br.readLine())!=null)
{
body.append(text);
body.append("\n");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I'm so confused. After reading this thread, I'm trying to write a List to internal storage onPause(), then read the List onResume(). Just for testing purposes, I'm trying to write a simple string as the example showed. I've got this to write with:
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = null;
try {
fos = openFileOutput(FILENAME, Context. MODE_WORLD_READABLE);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
fos.write(string.getBytes());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
fos.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
And I'm trying to read it in onResume() by calling:
try {
resultText01.setText(readFile("hello_file"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
resultText01.setText("exception, what went wrong? why doesn't this text say hello world!?");
}
Which of course uses this:
private static String readFile(String path) throws IOException {
FileInputStream stream = new FileInputStream(new File(path));
try {
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
/* Instead of using default, pass in a decoder. */
return Charset.defaultCharset().decode(bb).toString();
}
finally {
stream.close();
}
}
For some reason, resultText01.setText(...) isn't being set to "hello world!", and is instead calling the catch exception. I'm sorry if my lingo isn't correct, I'm new to this. Thanks for any pointers.
Instead of the following in your readFile(...) method...
FileInputStream stream = new FileInputStream(new File(path));
Try...
FileInputStream stream = openFileInput(path);
This is my first attempt at serializing/deserializing objects on any platform and, to put it mildly, I'm confused.
After implementing Serializable to my game object I output it to a file thus:
public void saveGameState(){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(theGame);//theGame is an instance of the custom class
//TGame which stores game info.
byte[] buf = bos.toByteArray();
FileOutputStream fos = this.openFileOutput(filename,
Context.MODE_PRIVATE);
fos.write(buf);
fos.close();
} catch(IOException ioe) {
Log.e("serializeObject", "error", ioe);
}
File f =this.getDir(filename, 0);
Log.v("FILE",f.getName());
}
This seems to work, in that I get no exceptions raised. I can only know for sure when I deserialize it. Which is where things go pear shaped.
public God loadSavedGame(){
TGame g=null;
InputStream instream = null;
try {
instream = openFileInput(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
try {
ObjectInputStream ois = new ObjectInputStream(instream);
try {
g= (TGame) ois.readObject();
return g;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
} catch (StreamCorruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
I got the basis of this code from here Android Java -- Deserializing a file on the Android platform and tried to modify it for my app. When running I get
05-31 23:30:45.493: ERROR/copybit(1279): copyBits failed (Invalid argument)
When the output should be loaded and the saved game start up from when it was saved.
Any help would be appreciated.
The error you've shown is not at all related to serialization: its actually a video display error. I'd suggest looking at the object BEFORE you serialize to make sure its not null, and I'd also suggest serializing to a file on the SD card to make sure you actually had data output (so use new FileOutputStream("/mnt/sdcard/serializationtest") as the output stream and new FileInputStream("/mnt/sdcard/serializationtest") as the input stream) while you are debugging; you can switch back to the context methods after it works, but make sure your sdcard is plugged in while you are doing this.
Finally, modify your logging to look like this:
try {
ObjectInputStream ois = new ObjectInputStream(instream);
try {
g= (TGame) ois.readObject();
return g;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
android.util.Log.e("DESERIALIZATION FAILED (CLASS NOT FOUND):"+e.getMessage(), e);
e.printStackTrace();
return null;
}
} catch (StreamCorruptedException e) {
android.util.Log.e("DESERIALIZATION FAILED (CORRUPT):"+e.getMessage(), e);
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
android.util.Log.e("DESERIALIZATION FAILED (IO EXCEPTION):"+e.getMessage(), e);
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
and see what error gets returned. I expect the serialization is failing somehow.
To seralize or deserialize anything you can use SIMPLE api. It is very easy to use. Download the file and use it in your program
Have a look here
http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#deserialize
Thanks Deepak
I have created below class to do the save and retrieve object.
public class SerializeUtil {
public static <T extends Serializable> void saveObjectToFile(Context context, T object, String fileName){
try {
FileOutputStream fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(object);
os.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static<T extends Serializable> T getObjectFromFile(Context context, String fileName){
T object = null;
try {
FileInputStream fis = context.openFileInput(fileName);
ObjectInputStream is = new ObjectInputStream(fis);
object = (T) is.readObject();
is.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
public static void removeSerializable(Context context, String filename) {
context.deleteFile(filename);
}
}