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
I have a Java program that reads some text from a file, line by line, and writes new text to an output file. But not all the text I write to my BufferedWriter appears in the output file after the program has finished. Why is that?
The details: the program takes a CSV text document and converts it into SQL commands to insert the data into a table. The text file has more than 10000 lines which look similar to following:
2007,10,9,1,1,1006134,19423882
The program seems to work fine except it just stops in the file randomly half way through creating a new SQL statement having printed it into the SQL file. It looks something like:
insert into nyccrash values (2007, 1, 2, 1, 4, 1033092, 259916);
insert into nyccrash values (2007, 1, 1, 1, 1, 1020246, 197687);
insert into nyccrash values (2007, 10, 9, 1
This happens after about 10000 lines but several hundred lines before the end of the file. Where the break happens is between a 1 and a ,. However, the characters doesn't seem important because if I change the 1 to a 42 the last thing written to the new file is 4, which is cutting off the 2 from that integer. So it seems like the reader or writer must just be dying after writing/reading a certain amount.
My Java code is as follows:
import java.io.*;
public class InsertCrashData
{
public static void main (String args[])
{
try
{
//Open the input file.
FileReader istream = new FileReader("nyccrash.txt");
BufferedReader in = new BufferedReader(istream);
//Open the output file.
FileWriter ostream = new FileWriter("nyccrash.sql");
BufferedWriter out = new BufferedWriter(ostream);
String line, sqlstr;
sqlstr = "CREATE TABLE nyccrash (crash_year integer, accident_type integer, collision_type integer, weather_condition integer, light_condition integer, x_coordinate integer, y_coordinate integer);\n\n";
out.write(sqlstr);
while((line = in.readLine())!= null)
{
String[] esa = line.split(",");
sqlstr = "insert into nyccrash values ("+esa[0]+", "+esa[1]+", "+esa[2]+", "+esa[3]+", "+esa[4]+", "+esa[5]+", "+esa[6]+");\n";
out.write(sqlstr);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
You need to close your OutputStream which will flush the remainder of your data:
out.close();
The default buffer size for BufferedWriter is 8192 characters, large enough to easily hold hundreds of lines of unwritten data.
You must close() your BufferedWriter. You must close() your BufferedWriter because it IS-A Writer and thus implements AutoCloseable, which means (emphasis added) it is
A resource that must be closed when it is no longer needed.
Some people say you must first call flush() for your BufferedWriter before calling close(). They are wrong. The documentation for BufferedWriter.close() notes that it "Closes the stream, flushing it first" (emphasis added).
The documented semantics of flushing (flush()) are
Flushes this stream by writing any buffered output to the underlying stream
So, you must close, and close will flush any buffered output.
Your output file does not include all the text you wrote to your BufferedWriter because it stored some of that text in a buffer. The BufferedWriter never emptied that buffer, passing it through to the file, because you never told it to do so.
Since Java 7, the best way to ensure an AutoCloseable resource, such as a BufferedWriter, is closed when it is not longer need is to use automatic resource management (ARM), also known as try-with-resources:
try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) {
// writes to out here
} catch (IOException ex) {
// handle ex
}
You must also close your BufferedReader when it is no longer need, so you should have nested try-with-resources blocks:
try (BufferedReader in = new BufferedReader(new FileReader("nyccrash.txt")) {
try (BufferedWriter out = new BufferedWriter(new FileWriter("nyccrash.sql"))) {
// your reading and writing code here
}
} catch (IOException ex) {
// handle ex
}
Do not be tempted (as other answers here suggest) just to call close() at the end of your method, when your code has "finished" using the writer. That will not work if your writing code throws an exception, and in particular if it throws an IOException.
A resource that must be closed when it is no longer needed.
finally {
out.close();//this would resolve the issue
}
Some things to consider:
BufferedWriter.close() flushes the buffer to the underlying stream, so if you forget to flush() and don't close, your file may not have all the text you wrote to it.
BufferedWriter.close() also closes the wrapped Writer. When that's a FileWriter, this will ultimately close a FileOutputStream and tell the OS that you're done writing to the file.
The garbage collector will automatically call close(), not on the BufferedWriter or the wrapped FileWriter, but on the FileOuputStream. So the OS will be happy, but you have to wait for the GC.
However, you always want to release OS resources as soon as you no longer need them. This goes for open files, database connections, print queues ... anything. Trust me on this one.
BufferedWriter.close() does clear up the internal character buffer, so that memory will be available for garbage collection, even while the BufferedWriter itself remains in scope.
So, Always close your resources (not just files) when you're done with them.
If you really want a peek under the covers, most of the Java API's source is available. BufferedWriter is here.
Your code does not appear to be closing the writer after you've finished writing to it. Add an out.close() (preferably in a finally block) and it should work properly.
you dint close your BufferedWriter.close it inside a finally block
finally {
out.close();//this would resolve the issue
}
Always close your resources (not just files) when you're done with them.
finally {
out.close();//this would resolve the issue
}
There might be situations when you want to flush the buffer without closing the file. In these situations you can use the flush-method.
Since you're using BufferedWriter you can also flush the buffer when appropriate:
out.flush()
This will write the rest of the buffer to the actual file. Close-method also flushes the buffer and closes the file.
out.close()
There might be situations when you want to flush the buffer without closing the file. In these situations you can use the flush-method.
You can also use BuffredWriter's newline-method instead of adding \n to the end of the line. Newline-method uses system specific line separator so your code works on different platforms.
out.newLine()
According to documentation it is no use calling flush() method. If you intent to use FileWriter then flush() would help you out.
Basically in this case, you just need to close, BufferedWriter.close() only. This will flush the remainder of your data.
create finally block and put the close method inside so that it will put all data without missing.
finally {
out.close();
}
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.
I am trying to clear the contents of a file I made in java. The file is created by a PrintWriter call. I read here that one can use RandomAccessFile to do so, and read somewhere else that this is in fact better to use than calling a new PrintWriter and immediately closing it to overwrite the file with a blank one.
However, using the RandomAccessFile is not working, and I don't understand why. Here is the basic outline of my code.
PrintWriter writer = new PrintWriter("temp","UTF-8");
while (condition) {
writer.println("Example text");
if (clearCondition) {
new RandomAccessFile("temp","rw").setLength(0);
// Although the solution in the link above did not include ',"rw"'
// My compiler would not accept without a second parameter
writer.println("Text to be written onto the first line of temp file");
}
}
writer.close();
Running the equivalent of the above code is giving my temp file the contents:(Lets imagine that the program looped twice before clearCondition was met)
Example Text
Example Text
Text to be written onto the first line of temp file
NOTE: writer needs to be able to write "Example Text" to the file again after the file is cleared. The clearCondition does not mean that the while loop gets broken.
You want to either flush the PrintWriter to make sure the changes in its buffer are written out first, before you set the RandomAccessFile's length to 0, or close it and re-open a new PrintWriter to write the last line (Text to be written...). Preferably the former:
if (clearCondition) {
writer.flush();
new RandomAccessFile("temp","rw").setLength(0);
You'll be lucky if opening the file twice at the same time works. It isn't specified to work by Java.
What you should do is close the PrintWriter and open a new one without the 'append' parameter, or with 'append' set to 'false'.
I want create text file but if the file already exists it should not create new file but should append the text to the content (at the end) of the existing file. How can I do it in Java?
for every one second I'm reading data from inputstream when i stop reading and again i start reading data at that time i should write to same file if file already exist
does I have to check the condition:
if(file.exists){
} else{
new File();
}
What I have to do?
You can use the following code to append to a file which already exists -
try {
BufferedWriter out = new BufferedWriter(new FileWriter("filename", true));
out.write("data");
out.close();
} catch (IOException e) { }
If the second argument in FileWriter's constructor is true, then bytes will be written to the end of the file rather than the beginning.
Quoting Stephen's comment:
...passing true as the 2nd
argument causes the file to be created
if it doesn't exist and to be opened
for appending if it does exist.
do i have to check the condition
if(file.exists){ }else{ new File(); }
No you don't have to do that: see other answers for the solution.
Actually, it would be a bad idea to do something like that, as it creates a potential race condition that might make your application occasionally die ... or clobber a file!
Suppose that the operating system preempted your application immediately after the file.exists() call returns false, and gave control to some other application. Then suppose that the other application created the file. Now when your application is resumed by the operating system it will not realise that the file has been created, and try to create it itself. Depending on the circumstance, this might clobber the existing file, or it might cause this application to throw an IOException due to a file locking conflict.
Incidentally, new File() does not actually cause any file system objects to be created. That only happens when you 'open' the file; e.g. by calling new FileOutputStream(file);
If you wish to append to the file if it already exists there's no need to check for its existence at all using exists(). You merely need to create a FileWriter with the append flag set to true; e.g.
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("foo.txt", true)));
pw.println("Hello, World");
pw.close();
This will create the file if it does not exist or else append to the end of it otherwise.