Android - Append Specfic Line In A Text File - java

hey people,
I have a text file which I need to append in my app. Now I could rewrite the entire file incorporating the changes to a specific line but I'm hoping there is a more efficient solution.
I know the line number I need to append however I'm unsure how to get to that line, preferably without looping through all of the others unless that is the only way. This is what I have so far which recreates the entire file:`
try {
FileOutputStream fOut = openFileOutput("tasklist.txt", MODE_APPEND);
BufferedOutputStream buf = new BufferedOutputStream(fOut);
OutputStreamWriter osw = new OutputStreamWriter(buf);
BufferedWriter writer = new BufferedWriter(osw);
for(int count = 0; count < str.size(); count++)
{
writer.write(str[count]);
writer.write("\r\n");
}
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "Error saving txt file", Toast.LENGTH_SHORT);
}`
Hopefully someone knows of a more efficient solution. Thanks.

There are some cleaner ways, but with file handling there isn't really a more efficient way (that I know of). You basically go from start to finish, as you have done, and append data. That's how file I/O works (it's not an Android or Java thing).
Still, you could try FileWriter to tidy it up a bit (the "true" param to the ctor means append):
FileWriter writer = new FileWriter(aFile, true));
try {
writer.write("append here\n");
} finally {
writer.close();
}
Be advised though, FileWriter uses the systems default encoding. This should be fine on Android, but be careful with it in general.
Here are some good general practices for dealing with reading and writing files with Java.
Also, depending on what you're doing with this file you're appending to (how often you are editing the same file, and from what processes), you may need to make a copy of it, and or deal with fysnc, to make sure you don't lose data on Android devices that use journaling filesystems.
To make your app more efficient though, maybe you could cache data in memory, and only write out the entire file (rather than append), at certain intervals, or when you're done. If you have a lot of data, a DB might even be appropriate.

Related

Java try with resources with Reader and Writer on the same file

try (Reader reader = Files.newBufferedReader(path);
Writer writer = Files.newBufferedWriter(path)) {
...
} catch (IOException exception) {
...
}
Can I use Reader and Writer which open the same file in try-with-resources? Is it safe?
Even if it's allowed, it's just waiting for problems to occur. Reader and Writer are not meant to work on the same file.
There are alternatives that you can look into. Good old RandomAccessFile is created to support both reading and writing. It's not great for text though. FileChannel, accessible from a RandomAccessFile or using FileChannel.open is newer but still doesn't work well with text.
This would be a bad practice. Different operating system will give you inconsistent results and it's asking for problems.
You'd be better off reading the file, writing to a temporary file, then replacing the old file with the temporary file when you're done.

Rollback or Reset a BufferedWriter

A logic that handles the rollback of a write to a file is this possible?
From my understanding a BufferWriter only writes when a .close() or .flush() is invoked.
I would like to know is it possible to, rollback a write or undo any changes to a file when an error has occurred?
This means that the BufferWriter acts as a temporary storage to store the changes done to a file.
How big is what you're writing? If it isn't too big, then you could write to a ByteArrayOutputStream so you're writing in memory and not affecting the final file you want to write to. Only once you've written everything to memory and have done whatever you want to do to verify that everything is OK can you write to the output file. You can pretty much be guaranteed that if the file gets written to at all, it will get written to in its entirety (unless you run out of disk space.). Here's an example:
import java.io.*;
class Solution {
public static void main(String[] args) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
// Do whatever writing you want to do here. If this fails, you were only writing to memory and so
// haven't affected the disk in any way.
os.write("abcdefg\n".getBytes());
// Possibly check here to make sure everything went OK
// All is well, so write the output file. This should never fail unless you're out of disk space
// or you don't have permission to write to the specified location.
try (OutputStream os2 = new FileOutputStream("/tmp/blah")) {
os2.write(os.toByteArray());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
If you have to (or just want to) use Writers instead of OutputStreams, here's the equivalent example:
Writer writer = new StringWriter();
try {
// again, this represents the writing process that you worry might fail...
writer.write("abcdefg\n");
try (Writer os2 = new FileWriter("/tmp/blah2")) {
os2.write(writer.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
It is impossible to rollback or undo changes already applied to files/streams,
but there are tons of alternatives to do so:
One simple trick is to clean the destination and redo the process again, to clean the file:
PrintWriter writer = new PrintWriter(FILE_PATH);
writer.print("");
// other operations
writer.close();
You can remove the content entirely and re-run again.
Or if you are sure the last line(s) are the problems, you may do remove last line actions for your purpose, such as rollback the line instead:
Delete last line in text file

Java File is disappearing from the path /tmp/hsperfdata_*username*/

This is very confusing problem.
We have a Java-application (Java8 and running on JBoss 6.4) that is looping a certain amount of objects and writing some rows to a File on each round.
On each round we check did we receive the File object as a parameter and if we did not, we create a new object and create a physical file:
if (file == null){
File file = new File(filename);
try{
file.createNewFile();
} catch (IOException e) {e.printStackTrace();}}
So the idea is that the file get's created only once and after that the step is skipped and we proceed straight to writing. The variable filename is not a path, it's just a file name with no path so the file gets created to a path jboss_root/tmp/hsperfdata_username/
edit1. I'll add here also the methods used from writing if they happen to make relevance:
fw = new FileWriter(indeksiFile, true); // append = true
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
.
.
out.println(..)
.
.
out.flush();
out.close(); // this flushes as well -> line above is useless
So now the problem is that occasionally, quite rarely thou, the physical file disappears from the path in the middle of the process. The java-object reference is never lost, but is seems that the object itself disappears because the code automatically creates the file again to the same path and keeps on writing stuff to it. This would not happen if the condition file == null would not evaluate to true. The effect is obviously that we loose the rows which were written to the previous file. Java application does not notice any errors and keeps on working.
So, I would have three questions which are strongly related for which I was not able to find answer from google.
If we call method File.CreateNewFile(), is the resulting file a permanent file in the filesystem or some JVM-proxy-file?
If it's permanent file, do you have any idea why it's disappearing? The default behavior in our case is that at some point the file is always deleted from the path. My guess is that same mechanism is deleting the file too early. I just dunno how to control that mechanism.
My best guess is that this is related to this path jboss_root/tmp/hsperfdata_username/ which is some temp-data folder created by the JVM and probably there is some default behavior that cleans the path. Am I even close?
Help appreciated! Thanks!
File.createNewFile I never used in my code: it is not needed.
When afterwards actually writing to the file, it probaby creates it anew, or appends.
In every case there is a race on the file system. Also as these are not atomic actions,
you might end up with something unstable.
So you want to write to a file, either appending on an existing file, or creating it.
For UTF-8 text:
Path path = Paths.get(filename);
try (PrintWriter out = new PrintWriter(
Files.newBufferedWriter(path, StandardOpenOption.CREATE, StandardOpenOption.APPEND),
false)) {
out.println("Killroy was here");
}
After comment
Honestly as you are interested in the cause, it is hard to say. An application restart or I/O (?) exceptions one would find in the logs. Add logging to a specific log for appending to the files, and a (logged) periodic check for those files' existence.
Safe-guard
Here we are doing repeated physical access to the file system.
To prevent appending to a file twice at the same time (of which I would expect an exception), one can make a critical section in some form.
// For 16 semaphores:
final int semaphoreCount = 16;
final int semaphoreMask = 0xF;
Semaphore[] semaphores = new Semaphore[semaphoreCount];
for (int i = 0; i < semaphores.length; ++i) {
semaphores[i] = new Semaphore(1, true); // FIFO
}
int hash = filename.hashcode() & semaphoreMask ; // toLowerCase on Windows
Semaphore semaphore = semaphores[hash];
try {
semaphore.aquire();
... append
} finally {
semaphore.release();
}
File locks would have been a more technical solution, which I would not like to propose.
The best solution, you perhaps already have, would be to queue messages per file.

How to show a specific screen when the program is opened the first time?

I was wondering how to make the program show a specific text it's ran by the first time, I know in android programming, a way to do this is by making a specification in the manifest. So I hope you'd understand me and can help me.
If you need to create a flag file use this
String FLAG_PTH="path/to file/flag.txt";
String flag="";
Use this code at load event of the page
try{
byte[] bfr=new byte[50];
FileInputStream IPS=new FileInputStream(COL_PTH);
int tn=0;
int nread=0;
while((nread=IPS.read(bfr))!=-1){
String clr=new String(bfr);
flag=clr;
}
IPS.close();
}
catch(FileNotFoundException fe){
System.out.println("ERR:9"+fe);
}
catch(IOException IOe){
System.out.println("ERR:10"+IOe);
}
if(flag=="True"){
// type your code for showing some text,or whatever it is.
try{
FileWriter FW=new FileWriter(FLAG_PTH);
BufferedWriter BF_Wr=new BufferedWriter(FW);
BF_Wr.write("TRUE");
BF_Wr.close();
}
catch(IOException e){
System.out.println("ERR:06"+e);
}
}
else {
//hide text and go through normal open
}
Well, I would have a text file with the word false in it,right at the top.Then in the programme you read that line, if it reads true then make it display whatever text you wish.After that you delete the file and make a new one(inside the if statement) with the same name only with true at the top this time.Therefore that if statement can only run again if that text file is changed to true.This is going to need buffered streams so read up on that: https://docs.oracle.com/javase/tutorial/essential/io/index.html .Alsojust a piece of advice keep all of your resources inside your jar file in a source folder as best as you can(its a lot less easier for users to mess with) doing this will cause you to need to use getResourceAsStream : https://m.youtube.com/watch?v=yksgU4SxoJY .I assure you it won't take long to go throught this.

writing text to an html file type

I am trying to write the result of the following method to a webpage. I think it is possible to do, I am just having trouble figuring out exactly how to do it. Any help would be very appreciated.
Thanks.
...
System.out.println("Final Register");
for (int i=0; i < ch.length; i++)
{
System.out.println(cd.getDenomLiteralAt(i)+" "+cd.getDenomNumAt(i));
}
}
...
In java there are many ways to write data on a file. To write text data the easiest way is by using a BufferedWriter.
See demo below
FileWriter fWriter = null;
BufferedWriter writer = null;
try {
fWriter = new FileWriter("fileName.html");
writer = new BufferedWriter(fWriter);
writer.write("<span>This iss your html content here</span>");
writer.newLine(); //this is not actually needed for html files - can make your code more readable though
writer.close(); //make sure you close the writer object
} catch (Exception e) {
//catch any exceptions here
}
All you need to do is know the path to the public HTML file of your webserver.
Run the Java code and write to a file below that path. It's no different than writing to any other file on a machine, except this one the world can see. Only thing is, if your Java will be creating the file, you should be sure to set protective enough permissions for the file. 0755 is moderately safe.

Categories

Resources