I am saving a log to a .txt file on the sdcard but once there is two lines saved, it overwrites it and starts over?
Here is my code:
public static Strin
This is the way it is done. The following sample code saves the details to a file upon clicking of the submit button:
Submit = (Button) findViewById(R.id.btnSubmit); //Instantiates the button in the onCreate method
Submit.setOnClickListener(new OnClickListener(){ //Called when the user clicks on the Submit button
@Override
public void onClick(View v) {
// In this case the text to be written is the selected text in a radio button from radioGroup
int Selection = AttendanceGroup.getCheckedRadioButtonId();
// find the radiobutton by returned id
RadioButton radiobutton = (RadioButton) findViewById(Selection);
// write on SD card file data in the text box
try {
//gets the current date since this is an attendance app.
Calendar c = Calendar.getInstance();
//Formats the date a desired
SimpleDateFormat date = new SimpleDateFormat("dd-MM-yy");
String getDate = date.format(c.getTime());
//writes the text to the file named attendance.txt which is created in the phone.
File myFile = new File("/sdcard/Albanapp/Attendance.txt");
FileWriter fOut = new FileWriter(myFile, true);
fOut.append(getDate + "\t" + getSelectedName.getSelectedItem().toString() + "\t" + radiobutton.getText().toString() + "\n");
fOut.flush();
fOut.close();
//Returns a statment to the user showing if the editing of the attendance.txt file was successful or not.
Toast.makeText(getBaseContext(),"Status Saved", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), "Attendance cannot be saved",
Toast.LENGTH_SHORT).show();
}
}
});
Hope this helps :)
You can simply use FileWriter without all the chained other writers. Be sure to call flush()
, as this ensures to write all buffered contents to the file.
If this still doesn't work, check you error output.
public static void writeToLog(Context context, String string) {
String text = getTimestamp() + " " + string + "\n"; //newline here
Writer out;
try {
out = new FileWriter(logFile, true);
out.append(text);
out.flush(); //ensure that all buffered characters are written to the target
} catch (IOException e) {
Log.d(Constants.APP_NAME, e.toString());
} finally {
if (out != null) {
out.close(); //ensure writer is closed
}
}
}
Using NIO you can write to the end of the file in more efficient way
public static void writeToLog(String string) {
String text = getTimestamp() + " " + string;
try {
java.nio.file.Files.write(java.nio.file.Paths.get("/file.txt"), text.getBytes(), java.nio.file.StandardOpenOptions.APPEND);
} catch (IOException ignore) { }
}
I am able to append the file using your code, can you please check this code
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class Test {
public static String getTimestamp() {
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"MMMdd HH:mm:ss", Locale.getDefault());
String currentTimeStamp = dateFormat.format(new Date());
return currentTimeStamp;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void writeToLog(String string) {
String text = getTimestamp() + " " + string;
// ONLY SAVES TWO LINES
try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new FileWriter("c:/log.txt", true)));
out.println(text);
out.close();
} catch (IOException e) {
}
}
public static void main(String[] args) throws Exception {
writeToLog("Connected to WIFI");
}
}
OUPUT :
Sep05 16:13:28 Connected to WIFI
Sep05 16:13:48 Connected to WIFI
Sep05 16:13:49 Connected to WIFI
Sep05 16:13:50 Connected to WIFI
Sep05 16:15:54 Connected to WIFI
Sep05 16:15:55 Connected to WIFI
Sep05 16:15:55 Connected to WIFI
Sep05 16:15:56 Connected to WIFI
Sep05 16:15:57 Connected to WIFI
Sep05 16:15:58 Connected to WIFI
Sep05 16:15:59 Connected to WIFI
Sep05 16:16:01 Connected to WIFI
You're only invoking write once, and you want to write to the file immediately. You don't need a BufferedWriter or a PrintWriter. They're overhead. Also, close should be invoked from a finally{} block, since you still need to close it if you have an error.
public static void writeToLog(Context context, String string) {
String text = getTimestamp() + " " + string + "\n";
Writer out = null;
try {
out = new FileWriter(logFile, true);
out.write(text, 0, text.length());
} catch (IOException e) {
Log.d(Constants.APP_NAME, e.toString());
} finally {
if (out != null){
out.close();
}
}
}
Only declare a BufferedWriter if you're going to be making multiple writes while the file is open. The purpose of the BufferedWriter is to improve the efficiency of multiple writes by keeping track of what has been input vs what's already been flushed.
Another issue I see is that because this is a static method and the writer isn't static, multiple invocations could try to simultaneously call writeToLog.
If you're using Java 7 or higher, you can simplify that a lot using a try with resources statement to auto-close your writer:
public static void writeToLog(Context context, String string) {
String text = getTimestamp() + " " + string + "\n";
try (FileWriter out = new FileWriter(logFile, true)) {
out.write(text, 0, text.length());
} catch (IOException e) {
Log.d(Constants.APP_NAME, e.toString());
}
}
You may want to consider keeping the writer open if you're going to log lines to it every second possibly multiple times, since opening/closing causes a lot of overhead. It also insures that all of your calls to writeToLog() are being sent to the same writer, in order.
private static final PrintWriter logWriter =
new PrintWriter(new BufferedWriter(new FileWriter(logFile, true)));
private static int flushCounter = 0;
private static final int flushFrequency = 5; // Flush the buffer every 5 lines
public static void writeToLog(Context context, String string) {
String text = getTimestamp() + " " + string + "\n";
try {
logWriter.write(text, 0, text.length());
} catch (IOException e) {
Log.d(Constants.APP_NAME, e.toString());
} finally {
flushCounter++;
if (flushCounter > flushFrequency){ // flush every 5 lines
logWriter.flush();
flushCounter = 0;
}
}
}
public void close(){
logWriter.close();
}
You can call close() from a finally{} block in your invoking code to clean up your logWriter.
Try changing
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(logFile, true)));
to
FileWriter fileWritter = new FileWriter(logFile,true); //true = append file
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
bufferWritter.write(YourData);
bufferWritter.close();