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.
Related
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.
Whenever the next segment of code is run, I get the new csv file created, but I don't get anything written to it:
PrintWriter fout = null;
try {
// create file
fout= new PrintWriter("EEGLogger.csv");
String headerFile = "IED_COUNTER, IED_INTERPOLATED, IED_RAW_CQ, IED_AF3, IED_F7, IED_F3, IED_FC5, IED_T7, " +
"IED_P7, IED_O1, IED_O2, IED_P8, IED_T8, IED_FC6, IED_F4, IED_F8, IED_AF4, " +
"IED_GYROX, IED_GYROY,IED_TIMESTAMP";
// Writes the header to the file
fout.println(headerFile);
fout.println();
...
I do a fout.close() in a finally statement, but that still doesn't help get any output to the file. Any ideas here?
Either:
You are looking in the wrong place, i.e. not the current working directory, or
You don't have write access to the current working directory.
If you had used a FileWriter and not got an IOException, that would rule out (2).
I've seen about a million answers and comments here this week claiming that the current working directory equals the location of the JAR file, but it doesn't.
You could open a FileWriter
fout = new PrintWriter(new FileWriter("EEGLogger.csv"));
...
fout.flush();
fout.close()
I believe the PrintWriter is intended for formatting and character encoding. api docs states Prints formatted representations of objects to a text-output stream and as well Methods in this class never throw I/O exceptions.
Using the FileWriter as parameter would force you to handle any IOException that may happen so if the file is not created or not writable, you will immediately get this information.
Another situation can happen if the file is created and you are just looking for the file at incorrect location. I'd suggest to create a File object too, to see where the file really resides (what's your real working directory)
File f = new File("EEGLogger.csv");
fout = new PrintWriter(new FileWriter(f));
System.out.println(f.getAbsolutePath());
I am trying to simply read a text document in java. The file is being found by my program; I can see that it is able to determine the correct absolute path through various tests, but the problem seems to be that my program doesn't have permission to view the file?
File names = new File("names.txt");
if(names.setReadable(true, false (edit: true)))
System.out.println("Can now be read");
if(names.canRead())
System.out.println("Can be read");
FileInputStream fs = new FileInputStream(names);
BufferedReader br = new BufferedReader(new InputStreamReader(fs));
The boolean expression in each if statement evaluates to false, and I cannot understand why, or how to change it. I run into a FileNotFoundException where I attempt to create a new FileInputStream, which I read is due the the file being unreadable.
EDIT: Now I have changed the second paramater for the setReadable method call to true, and that part works (it prints "Can now be read"); so it seems that the file is being found and set as readable but still the second if statement fails and the program cannot access the text document.
This should be:
if(names.setReadable(true, true))
The second argument should be true so that the owner can access the file.
If you set it to false the program won't be able to read the file.
For more information read here.
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 have this code that copies an array elements into a text file, and after copying the files I have a button which opens the file i-copied.
try
{
print = new PrintWriter("C:\\Users\\Jofrank\\workspace\\Java\\src\\payroll\\report.txt");
print.println("EMPLOYEES PAYROLL RECORD AS OF "+dateFormat.format(date));
print.println();
for(int x=0;x<department.length;x++)
{
print.println("DEPARTMENT: "+department[x].toUpperCase());
print.println("\tPAYROLL PERIOD\tEMPLOYEE NUMBER\tNAME\tPAY RATE\tHOURS WORKED\tSALARY");
print.println();
for(int y=0;y<trans.length;y++)
{
if(trans[y] == null)
{
continue;
}
if(trans[y].getDepartment().equals(department[x]))
{
print.println("\t"+trans[y].getPayrollPeriod()+"\t"+trans[y].getEmpNo()+"\t\t"+trans[y].getName()+"\t"+trans[y].getPayRate()+"\t\t"+trans[y].getHoursWorked()+"\t\t"+String.format("%,.2f", (trans[y].getPayRate()*trans[y].getHoursWorked())));
total+=(trans[y].getPayRate()*trans[y].getHoursWorked());
}
}
print.println("\t\t\t\t\t\t\t\t\tTOTAL:\t"+String.format("%,.2f", total));
print.println();
total=0;
}
print.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
Unfortunately, My text file was not UPDATED unless i-close the system.
Is there a way that my text file will be updated automatically without CLOSING the system?
You can actually create a PrintWriter with autoFlush turned on:
print = new PrintWriter(new FileOutputStream
("C:\\Users\\Jofrank\\workspace\\Java\\src\\payroll\\report.txt"), true);
Here 2nd parameter is true. As per Javadoc:
autoFlush - A boolean; if true, the println, printf, or format
methods will flush the output buffer
That depens much on the system.
flush() usually should work, but this is all not garuanteed.
There are some embedded flash file system where you might call sync, too.
But for the first apporach try flush()
You need to empty your stream for it to be written to the file. As others have suggested, use .flush() to accomplish this without having to .close() your stream. Otherwise I believe .close() automagically calls .flush() for you to ensure your stream has been emptied and it's contents written to disk or wherever you are directing it.
In documentation it is said that PrintWriter does not flush lines automatically.
You may need to use different constructor for PrintWriter:
PrintWriter(File file)
but you have to open the file itself and then close it after writing is done.