Writing data to a file - java

I want to create a folder from inside my app. Inside the folder, I want to create just one file (say recents) where the app will keep writing data line by line on each launch.
private void saveForRecents(String phoneNumber) {
//Need to open File and write the phonenumbers that has been passed into it
try{
File mydir = getDir("recents", 0);
//Creating an internal dir;
File fileWithinMyDir = new File(mydir, "recents");
//Getting a file within the dir.
FileWriter fw = new FileWriter(fileWithinMyDir.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(phoneNumber);
bw.newLine();
bw.flush();
bw.close();
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Failed to write into the file", Toast.LENGTH_LONG).show();
}
}
How do I access the contents of the recents file that is inside my directory mydir? And I want to access the data line by line as I'm writing data line by line. I would really appreciate if someone took their time to explain me how to do it because I need to learn it. Also please let me know if I am doing something wrong.

Based on what you are doing, I think using SharedPreferences is a better way to go. It won't be overwritten by someone else, and it's hidden from someone messing around in a file explorer. Here's a quick example assuming you have your recent phone numbers in some sort of an array. Other methods are possible of course.
SharedPreferences Prefs = getSharedPreferences("RecentPhoneNumbers", MODE_PRIVATE);
Editor e = Prefs.edit();
e.clear();
for (String s : RecentPhoneArray)
{
e.putString(s);
}
e.commit();
Then to load them the next time the application starts or needs a reload:
SharedPreferences Prefs = getSharedPreferences("RecentPhoneNumbers", MODE_PRIVATE);
for (Map.Entry<String, ?> entry : Prefs.getAll().entrySet())
{
String s = entry.getValue().toString();
RecentPhoneArray.add(s);
}

After a long time I figured out the second part of my problem. This might be useful for other users if they come across the same problem.
For Making a custom directory (here recents) and a custom file (here recent)
try
{
File mydir = getDir("recents", 0);
File fileWithinMyDir = new File(mydir, "recent");
//true here lets the data to be added in the same file in the next line
// No value at all or a false will overwrite the file
FileWriter fw = new FileWriter(fileWithinMyDir.getAbsoluteFile(), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("Anything you want to write");
bw.newLine();
bw.flush();
bw.close();
}catch(Exception e){
Toast.makeText(getApplicationContext(), "Failed to write into the file", Toast.LENGTH_LONG).show();
}
The following code helps to read the same file(here recent) inside the same directory(here recents)
try
{
File mydir = this.getDir("recents", 0);
File fileWithinMyDir = new File(mydir, "recent");
try
{
// open the file for reading
InputStream instream = new FileInputStream(fileWithinMyDir);
if (instream != null)
{
// prepare the file for reading
InputStreamReader inputreader = new InputStreamReader(instream);
BufferedReader buffreader = new BufferedReader(inputreader);
String line;
while ((line = buffreader.readLine())!= null)
{
// do something with the line
}
instream.close();
}
}
catch (Exception ex)
{
// print stack trace.
}
finally
{
// close the file.
}
}
catch(Exception e)
{
e.printStackTrace();
}
One important thing to note is that if a directory recents here and file inside it recent here does not exist then it will automatically be created in the first run. From the second run it will start referencing it rather than recreating the whole thing again...
Hope this will help some users

Related

New file not getting called on renameTo()

I used the following code to edit the file OIMV2Migration.sh on linux.
String oldFileName = "OIMV2Migration.sh";//file to be edited
String tmpFileName = "tmp_try.dat"; //new file containing changes
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader(oldFileName));
bw = new BufferedWriter(new FileWriter(tmpFileName));
String line;
while ((line = br.readLine()) != null) {
if (line.contains("SURBHI")) {
line = line.replace("SURBHI MITTAL" , "SURBHI GUPTA");}
bw.write(line+"\n");
}
} catch (Exception e) {
return;
} finally {
try {
if(br != null)
br.close();
} catch (IOException e) {
//
}
try {
if(bw != null)
bw.close();
} catch (IOException e) {
//
}}
//delete the old file
File oldFile = new File(oldFileName);;
oldFile.delete();
//rename the new file to old file
File newFile = new File(tmpFileName);
System.out.println(newFile.getAbsolutePath());
Boolean success = newFile.renameTo(oldFile);
System.out.println(newFile.getAbsolutePath());
Here , the file is getting updated correctly , but the absolute path of the newFile is always pointing to "tmp_try.dat , both before renameTo() and after renameTo() is executed.
I got to know from stack overflow link that the absolute path of the file instance does not change , it remains same.
But my problem is there is another file in my system idmlcm.sh which is internally calling OIMV2Migration.sh.But after this method is executed , idmlcm.sh is not able to call OIMV2Migration.sh as if it cant find this file.
Although the file exists in the correct directory only.
According to JAVA Documentation
Behavior of renameTo :
Many aspects of the behavior of this method are inherently
platform-dependent: The rename operation might not be able to move a
file from one filesystem to another, it might not be atomic, and it
might not succeed if a file with the destination abstract pathname
already exists. The return value should always be checked to make sure
that the rename operation was successful.
In your case, first you are deleting oldFile and than rename that tmpFile to oldFileName, that actually works perfect, but when you call newFile.getAbsolutePath() will print path of tmpFile because the Object newFile still refers to old path only. You need to re-create the File Object to access your renamed File.

Deleting an existing file in java and renaming the temp file [duplicate]

I am doing a project in Java using NetBeans and I need to modify a file. So I overwrite the whole file in another temporary file, but at the end I could not rename the temporary file or delete the main file. Any solutions?
File tf = new File("F:\\nb\\project_inventory\\temp.tmp");
FileReader fr = new FileReader("F:\\nb\\project_inventory\\Employee_info.txt");
BufferedReader br =new BufferedReader(fr);
FileWriter fw = new FileWriter(tf);
PrintWriter bw =new PrintWriter(fw);
String line;
while((line=br.readLine())!=null)
{
if(line.contains(del_id)) continue;
bw.println(line);
}
bw.close();
fw.close();
br.close();
fr.close();
File real =new File("F:\\nb\\project_inventory\\Employee_info.txt");
real.delete();
tf.renameTo(real);
I just tried 5 of the above project lines as below and got the desired result,
File real =new File("F:\\nb\\project_inventory\\Employee_info.txt");
real.delete();
File tf = new File("F:\\nb\\project_inventory\\temp.tmp");
try{
tf.createNewFile(); // for creating the new file
}
catch(IOException e){
e.printstacktrace();
}
File real =new File("F:\\nb\\project_inventory\\Employee_info.txt");
tf.renameTo(real);
Employee_info.txt is getting deleted as well as temp.tmp is getting renamed as Employee_info.txt too.
Also, it is always recommended to put the code for delete/rename inside try/catch block like below:
try{
File real =new File("F:\\nb\\project_inventory\\Employee_info.txt");
real.delete();
}
catch(IOException e){
e.printstacktrace();
}
Please provide the error message, to help you further.

How can I save java all lines from java console output to a text file and properly append it?

I am new to Java and have been trying to string some open source code together to search tweets and finally was able to succeed. Then I wanted to save the output to a text file. I searched and reviewed console out methods, filewriter, printwriter and I found one on here that works but it's saving only one tweet and overwrites the previous one it saves. How can I properly append the existing text file without overwriting a previous save and make sure it saves all the tweets from the console screen? Example code below:
JSONObject js = new JSONObject(buff.toString());
JSONArray tweets = js.getJSONArray("results");
JSONObject tweet;
for(int i=0;i<tweets.length();i++) {
tweet = tweets.getJSONObject(i);
PrintWriter out;
try {
out = new PrintWriter(new FileWriter("C:\\tweet\\outputfile.txt"));
System.out.println((i+1)+")http://twitter.com/"+tweet.getString("from_user")+" at "+tweet.getString("created_at"));
System.out.println(tweets.getJSONObject(i).getString("text")+"\n");
out.println((i+1)+")http://twitter.com/"+tweet.getString("from_user")+" at "+tweet.getString("created_at"));
out.println(tweets.getJSONObject(i).getString("text")+"\n");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You are so tantalizingly close. You just need to open the FileWriter with append set to true. Append will make it add to the end of the file, as opposed to overwriting it every time.
out = new PrintWriter(new FileWriter("C:\\tweet\\outputfile.txt", true));
Change this line (Because it will erase your previously written data):
out = new PrintWriter(new FileWriter("C:\\tweet\\outputfile.txt"));
For (Here you are setting Append mode to true)
out = new PrintWriter(new FileWriter("C:\\tweet\\outputfile.txt"), true);
Default mode is set to false so it will overwrite your file.
Instead of creating object of PrintWriter and FileWriter object during each iteration of your for loop you should initialize PrintWriter outside of you for loop(its will improve performance)finally to release resource.
PrintWriter out = null ;
try
{
// putting
out = new PrintWriter(new FileWriter("C:\\tweet\\outputfile.txt"),true); // appending file if exists.
// JSON Parsing instructions
for(int i=0;i<tweets.length();i++)
{
// processing logic and write operation to file
}
}
catch(CustomExceptions e) {//All other exception handling}
catch(Exception e){//Generic exception handling }
finally{
if(out != null
{
out.close();
}
}
public final String path ="your path"
PrintWriter pw = new PrintWriter(new FileWriter(path),true);/*automatically append the line you want to save and if false it will overwrite the data */
pw.write("what ever you want")
pw.close();

Saving String Input on Android

Right, I've been trying to find a solution to this for a good while, but it's just not working for some reason.
In short, what I want to do is save every input String the user inputs into a file. Every time the activity is created again, I want to re-input these strings into a new instance of an object.
This code is what I use to create the file and read info from it, used in the onCreate() method of activity
try {
String brain = "brain";
File file = new File(this.getFilesDir(), brain);
if (!file.exists()) {
file.createNewFile();
}
BufferedReader in = new BufferedReader(new FileReader(file));
String s; // This feeds the object MegaAndroid with the strings, sequentially
while ((s = in.readLine()) != null) {
MegaAndroid.add(s);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
After that, every time the user inputs some text, the strings are saved onto the file:
try {
String brain = "brain";
File file = new File(this.getFilesDir(), brain);
if (!file.exists()) {
file.createNewFile();
}
BufferedWriter out = new BufferedWriter(new FileWriter(file));
out.write(message); // message is a string that holds the user input
out.close();
} catch (IOException e) {
e.printStackTrace();
}
For some reason, however, every time the application is killed, the data is lost.
What am I doing wrong?
EDIT: Also, if I were to access this file from another class, how can I?
As we discussed in the commend section the chief problem with the code is that your execution of FileWriter occurred prior to your FileReader operation while truncating the file. For you to maintain the file contents you want to set the write operation to an append:
BufferedWriter out = new BufferedWriter(new FileWriter(file,true));
out.write(message);
out.newLine();
out.close();
However, if every entry on the EditText is received then shipped into the file you'll just be writing data byte after byte beside it. It is easy to get contents similar to
This is line #1This is line #2
Instead of the desired
This is line #1
This is line #2
which would be corrected by having the BufferedWriter pass a newline after each write to the file.
This is what I do for file reading.
try{
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/whereyouwantfile");
dir.mkdirs();
Log.d(TAG,"path: "+dir.getAbsolutePath());
File file = new File(dir, "VERSION_FILENAME");
FileInputStream f = new FileInputStream(file);
//FileInputStream fis = context.openFileInput(VERSION_FILENAME);
BufferedReader reader = new BufferedReader(new InputStreamReader(f));
String line = reader.readLine();
Log.d(TAG,"first line versions: "+line);
while(line != null){
Log.d(TAG,"line: "+line);
//Process line how you need
line = reader.readLine();
}
reader.close();
f.close();
}
catch(Exception e){
Log.e(TAG,"Error retrieving cached data.");
}
And the following for writing
try{
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/whereyouwantfile");
dir.mkdirs();
File file = new File(dir, "CONTENT_FILENAME");
FileOutputStream f = new FileOutputStream(file);
//FileOutputStream fos = context.openFileOutput(CONTENT_FILENAME, Context.MODE_PRIVATE);
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(f));
Set<String> keys = Content.keySet();
for(String key : keys){
String data = Content.get(key);
Log.d(TAG,"Writing: "+key+","+data);
writer.write(data);
writer.newLine();
}
writer.close();
f.close();
}
catch(Exception e){
e.printStackTrace();
Log.e(TAG,"Error writing cached data.");
}
You can use the private mode if you don't want the rest of the world to be able to see your files, but it is often useful to see them when debugging.

Cannot delete file Java

I have this method that gets the last line of a .txt file and creates a new temp file without that line. But when I try to delete the .txt that has the line I want to delete (so then I can rename the temp file) for some reason I can't. This is the code:
void removeFromLocal() throws IOException {
String lineToRemove = getLastLine();
File inputFile = new File("nexLog.txt");
File tempFile = new File("TempnexLog.txt");
BufferedReader reader = null;
BufferedWriter writer = null;
try {
reader = new BufferedReader(new FileReader(inputFile));
writer = new BufferedWriter(new FileWriter(tempFile));
String currentLine;
int i = 0;
while ((currentLine = reader.readLine()) != null) {
i++;
String trimmedLine = currentLine.trim();
if (!trimmedLine.equals(lineToRemove)) {
if (i != 1) {
writer.newLine();
}
writer.write(currentLine);
}
}
reader.close();
reader = null;
writer.flush();
writer.close();
writer = null;
System.gc();
inputFile.setWritable(true);
if (!inputFile.delete()) {
System.out.println("Could not delete file");
return;
}
if (!tempFile.renameTo(inputFile)) {
System.out.println("Could not rename file");
}
//boolean successful = tempFile.renameTo(inputFile);
} catch (IOException ex) {
Logger.getLogger(dropLog.class.getName()).log(Level.SEVERE, null, ex);
}
}
Whats funny is that when I press the button that calls the method once, nothing happens ("Could not delete file"), the second time it works fine and the 3rd I get "Could not rename file".
The file cannot be deleted when it's been opened by another process. E.g. in notepad or so or maybe even another FileReader/FileWriter on the file somewhere else in your code. Also, when you're executing this inside an IDE, you'll risk that the IDE will touch the file during the background scan for modifications in the project's folder. Rather store the files in an absolute path outside the IDE's project.
Also, the code flow of opening and closing the files has to be modified so that the close is performed in the finally block. The idiom is like this:
Reader reader = null;
try {
reader = new SomeReader(file);
// ...
} finally {
if (reader != null) try { reader.close(); } catch (IOException logOrIgnore) {}
}
Or, if you're already on Java 7, use the automatic resource management instead.
try (Reader reader = new SomeReader(file)) {
// ...
}
Further I recommend to use File#createTempFile() instead to create temp files. This way an unique temp filename will be generated and thus you prevent the very same temp file being written and renamed by multiple processes.
File tempFile = File.createTempFile("nexLog", ".txt");
Does BufferedReader close the nested reader (not mentioned in the doc)? You have to make sure, by checking if setWritable was successful.Otherwise you need to close FileReader too, and I would recommend because in case you close it twice there is no harm... by the way GC call is more harmful than useful.

Categories