I am making a bookmark for web browser app this code is saving and loading the data but it is not appending data in new line...every time i am pressing the button it is overwriting previous data ..I want that every time i call bookmarkload(); method in main activity it should save data in new line instead of overwriting it..Please help me as i am new to android tell what line to enter where..so that it start appending data..Thanks in advance ..please give answer in detail if possible.
public class Bookmark {
FileOutputStream fos;
FileInputStream fis = null;
public void bookmarksave(Context context,String FILENAME,String data){
try {
fos = context.openFileOutput(FILENAME, 0);
fos.write(data.getBytes());
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String bookmarkload(Context context,String FILENAME){
String collected =null;
try{
fis =context.openFileInput(FILENAME);
byte[] dataArray = new byte[fis.available()];
while(fis.read(dataArray) != -1){
collected = new String(dataArray);
fis.close();
}
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return collected;
}
}
fos.write(System.getProperty("line.separator").getBytes());
Try this one... new data will be appended in new line..
change the Line fos = context.openFileOutput(FILENAME, 0); to
fos = context.openFileOutput(FILENAME, Context.MODE_APPEND);
This will open your file in append mode, instead of the default (override) mode.
You should also add a new line, otherwise you continue in the same line as before:
fos.write(System.getProperty("line.separator").getBytes());
You can use SharedPreferences to save your bookmark.It's very convenience.And if you want to use File to store them.You can use new FileOutputStream(filename,true) ,true means bytes will be written to the end of the file rather than the beginning.
Related
I am trying to read a file i download from Dropbox (using Dropbox CORE API).
private void downloadropboxfile(final String filename)
{
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
File file = new File(getCacheDir(),filename);
if(!file.exists())
file.createNewFile();
FileOutputStream outputStream = new FileOutputStream(file);
DropboxAPI.DropboxFileInfo info=mDBApi.getFile("/" + filename, null, outputStream, null);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
Then in another function i call the downloaddropbox function and try to read the file content on Onclick event.
String filename = "info.txt";
downloadropboxfile(filename);
String strLine = "";
try {
InputStream instream = new FileInputStream(new File(getCacheDir(),filename));
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader bReader = new BufferedReader(inputreader);
/** Reading the contents of the file , line by line */
while ((strLine = bReader.readLine()) != null) {
mTestOutput.setText(strLine);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
My problem is that i don't get the file content immediately. I need to click the button 3-4 times in order to read the file content. What's the problem with my code?
You're calling downloaddropboxfile, which starts a new thread to download the file. But then you're immediately trying to read the local file (before it's downloaded).
If you haven't worked with threading before, the important thing to understand is that downloaddropboxfile returns almost immediately, but the thread it starts keeps running in the background. You'll need to wait for it to finish before trying to do something with the downloaded file.
i'm using the below code to save log data to a file.
However, every time a new call is made, the old content is gone.....
i can't figure out what the issue is however....
public void writeToFile(String fileName, String textToWrite) {
FileOutputStream fOut = null;
try {
File root = new File(Environment.getExternalStorageDirectory() , fileName);
if (! root.exists()){
root.createNewFile();
}
fOut = new FileOutputStream(root);
OutputStreamWriter myOutWriter = new OutputStreamWriter(fOut);
myOutWriter.append(textToWrite);
myOutWriter.flush();
myOutWriter.close();
}
catch (Exception e) {
new MailService().mailMessage(e.toString());
}
finally{
if(fOut != null){
try{
fOut.close();
}
catch(Exception ex){
}
}
}
}
You need to pass second parameter boolean true to FileOutputStream constructor which indicates the file will be opened in append mode rather than write mode.
FileOutputStream out=new FileOutputStream("myfile");
Everytime you execute the above code it will open the file in write mode so that the new content will overwrite the old content. However, the FileOutputStream constructor accepts a second argument which is a boolean indicating whether to open the file in append mode.
FileOutputStream out=new FileOutputStream("myfile",true);
The above code will open the file in append mode so that the new content will be appended to the end of old content.
To know more about FileOutputStream constructors see this.
So the Title pretty much sums up my problem, but I'm not sure what I'm doing wrong as far as code goes.
Here's the snipbit where I write to the file:
try {
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fos);
osw.append(assignmentTitle + "\n" + assignmentDate + "\n");
osw.flush();
osw.close();
} catch (FileNotFoundException e) {
//catch errors opening file
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Edit: This is where I read from the file every time the activity is called
private void readDataFromFile() {
try {
//Opens a file based on the file name stored in FILENAME.
FileInputStream myIn = openFileInput(FILENAME);
//Initializes readers to read the file.
InputStreamReader inputReader = new InputStreamReader(myIn);
BufferedReader BR = new BufferedReader(inputReader);
//Holds a line from the text file.
String line;
//currentAssignment to add to the list
Assignment currentAssignment = new Assignment();
while ((line = BR.readLine()) != null) {
switch (index) {
case 0:
//Toast.makeText(this, line, Toast.LENGTH_LONG).show();
currentAssignment.setTitle(line);
index++;
break;
case 1:
//Toast.makeText(this, Integer.toString(assignmentListIndex), Toast.LENGTH_LONG).show();
currentAssignment.setDate_due(line);
Statics.assignmentList.add(assignmentListIndex, currentAssignment);
index = 0;
assignmentListIndex++;
currentAssignment = new Assignment();
break;
default:
Toast.makeText(this, "error has occured", Toast.LENGTH_SHORT).show();
break;
}
}
BR.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Thats in a function when the user clicks on create a new assignment. When they click the save button on the assignment, it's supposed to save that assignment to a file and then I read it later and display it in a listView. What it's doing is displaying the first item in the listView and when I create a new assignment, it's overwriting the previous text in save file and replacing it in the listView. If you guys need me to post more code Let me know. I'm so confused as to why this isn't working :(
Instead of Context.MODE_PRIVATE, use Context.MODE_APPEND. This mode appends to an existing file instead of erasing it. (More detail on those in the openFileOutput docs.)
Instead of using OutputStreamWriter Class i suggest you to use BufferedWriter Class just as follows,
private File myFile = null;
private BufferedWriter buff = null;
myFile = new File ( "abc.txt" );
buff = new BufferedWriter ( new FileWriter ( myFile,true ) );
buff.append ( assignmentTitle );
buff.newLine ( );
buff.append ( assignmentDate );
buff.newLine ( );
buff.close();
myFile.close();
Hi in my application I am saving string information entered by the user. then serializing those string for retrival later. When I go to open the file to where they are saved I always only get the last string that was entered. Can you see where i am going wrong?
This is the retrival code
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.lightlist);
adapter = new ArrayAdapter<String>(LightList.this, android.R.layout.simple_list_item_1, lightNames);
refreshBut = (Button)findViewById(R.id.button1);
try {
File file = getCacheDir();
fis = new FileInputStream(new File(file, LightSetup.FILENAME ));
ois = new ObjectInputStream(fis);
String a;
while((a = (String)ois.readObject()) != null){
adapter.add(a);
setListAdapter(adapter);
}
ois.close();
} catch (FileNotFoundException e) {e.printStackTrace();} catch (StreamCorruptedException e){e.printStackTrace();
} catch (IOException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}
}//end onCreate
And this is the serializing code
public void onClick(View arg0) {
String stringData = data.getText().toString();
try {
File file = getCacheDir();
fos = new FileOutputStream(new File(file,FILENAME ));
os = new ObjectOutputStream(fos);
os.writeObject(stringData);
fos.close();
os.close();
} catch (IOException e) {e.printStackTrace();}
Intent i = new Intent("com.Sonny.HCIProject.CreateConfirm");
startActivity(i);
finish();
}//end onClick
You are doing 2 things in a wrong way:
You don't do setListAdapter in a loop, though it might not do you any harm, you don't need to.
The code in your onClick method does not do what you expect, it simply overwrites the data you serialized in the last time. You need to re-construct the objects you serialized in the past using ObjectInputStream and then add your current object to the object graph(I think you need a List), then you can safely serialize all your objects in the file without overwriting your old objects.
Even you can serialize objects like that, I recommend you store your data in SQLite database in stead of using Java serialization, reconstructing a whole lot of unrelated objects just to store another object is overkill. With SQLite, you INSERT a record to the database, and then you can SELECT all records from the database, it is fast and your code will be more succinct.
I want to store a few values in the form of high scores. But since I'm not going to be storing more than 5 values, using SQLite doesn't seem appropriate. Another option I was considering was a flat file, but I'm not sure how to go about that...
See here for your Data Storage options. I suppose that in your case the easiest will be to use SharedPreferences.
You could also use Internal Storage to save data in a file that is private to your application. I wouldn't recommend to use External Storage for storing high scores.
If it's an array you can use this:
public void saveArray(String filename, String[] output_field) {
try {
FileOutputStream fos = new FileOutputStream(filename);
GZIPOutputStream gzos = new GZIPOutputStream(fos);
ObjectOutputStream out = new ObjectOutputStream(gzos);
out.writeObject(output_field);
out.flush();
out.close();
}
catch (IOException e) {
e.getStackTrace();
}
}
#SuppressWarnings("unchecked")
public String[] loadArray(String filename) {
try {
FileInputStream fis = new FileInputStream(filename);
GZIPInputStream gzis = new GZIPInputStream(fis);
ObjectInputStream in = new ObjectInputStream(gzis);
String[] read_field = (String[])in.readObject();
in.close();
return read_field;
}
catch (Exception e) {
e.getStackTrace();
}
return null;
}
You just call it like this:
Save Array: saveArray("/sdcard/.mydata/data.dat", MyArray);
Load Array: String[] MyArray = loadArray("/sdcard/.mydata/data.dat");
You can see an example at http://androidworkz.com/2010/07/06/source-code-imageview-flipper-sd-card-scanner/