Using PrintWriter with files - java

In case I have the following code:
private PrintWriter m_Writer;
m_Writer = new PrintWriter(new FileWriter(k_LoginHistoryFile));
I am writing to a local file on server which name is k_LoginHistoryFile.
Now, as my program runs it doing writings to this file so how can I delete all the file content between each writes?
I think it is important as I don't want to write to a file which will eventually have current updated information on its beginning + not up to date info at its end.
Thanks in advance

This expression:
new FileWriter(k_LoginHistoryFile)
will truncate your file if it exists. It won't just overwrite the start of the file. It's not clear how often this code is executing, but each time it does execute, you'll start a new file (and effectively delete the old contents).

I think it is important as I don't want to write to a file which will eventually have current updated information on its beginning + not up to date info at its end.
If you want to keep a running output file (and you can't keep the file open), consider this constructor: FileWriter(String, boolean)
If the boolean is true, your updated information will be at the end of the file.

Related

Upload retry mechanism using JSch library

I have a file to upload (say abc.pdf). Very first time I want to upload this file as a temp file (say abc.pdf.temp). Then , if the file is successfully transferred (fully transferred) then I need to rename it to its original name (abc.pdf). But if the file is not fully transferred then I need to delete the temp file that I uploaded initially since I don't want to keep a corrupted file in the server. Is this achievable to do using this JSch library. Below is the sample code. Does this code make sense to achieve this?
Sample Code:
originalFile = 'abc.pdf';
tempFile = 'abc.pdf.temp';
fileInputStream = createobject("java", "java.io.FileInputStream").init('C:\abc.pdf');
SftpChannel.put(fileInputStream,tempFile);
// Comparing remote file size with local file
if(SftpChannel.lstat(tempFile).getSize() NEQ localFileSize){
// Allow to Resume the file transfer since the file size is different
SftpChannel.put(fileInputStream,tempFile,SftpChannel.RESUME);
if(SftpChannel.lstat(tempFile).getSize() NEQ localFileSize){
// Check again if the file is not fully transferred (During RESUME) then
// deleting the file since dont want to keep a corrupted file in the server.
SftpChannel.rm(tempFile);
}
}else{//assuming file is fully transferred
SftpChannel.rename(tempFile ,originalFile);
}
It's very unlikely that after the put finishes without throwing, the file size won't match. It can hardly happen. Even if it happens, it makes little sense to call RESUME. If something catastrophic goes wrong that is not detected by put, RESUME is not likely to help.
And even if you want to try with RESUME, it does not make sense to try once. If you believe it makes sense to retry, you have to keep retrying until you succeed, not only once.
You should catch exception and resume/delete/whatever. That's the primary recovery mechanism. This is 100x more likely to happen than 1.

Writing and reading a file from two processes

You have:
A process (READER) that opens a text file (TEXTFILE), reads all the lines until the EOF and waits for new lines to appear.
The READER is implemented in Java and the waiting part uses java.nio.file.WatchService, which if I understand correctly on Linux uses inotify. I am not sure which is more relevant to the question.
The implementation is quite simple (exception handling and some ifs left out for brevity):
WatchService watcher;
watcher = FileSystems.getDefault().newWatchService();
Path logFolder = Paths.get("/p/a/t/h");
logFolder.register(watcher, ENTRY_MODIFY);
reader = Files.newBufferedReader("TEXTFILE", Charset.forName("US-ASCII"));
key = watchService.take();
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
doSomethingWithTheNewLine(reader.readLine());
}
Now, if I run READER and
Open TEXTFILE in an editor, add a line and save it, the result is that the READER doesn't seem to get the new line
If, on the other hand, I do something like this in bash
while true; do echo $(date) ; sleep 2; done >> TEXTFILE
then the READER does get the new lines
EDIT:
As far as I can see, the difference here that may matter is that in the first case, the editor loads the content of the file, closes it (I assume), and on saving it opens the file again and synchronizes the content with the file system, while the bash line keeps the file opened... how would that make any difference, I am not sure
I suppose the simple question is why???
They way I understood scenario like this is that Linux is using some sort of locking when >1 processes need access to the same file on filesystem at the same time. I also thought that when a process A opens a file descriptor to a file at time t0, it gets let's say a snapshot of what the file content was at t0. Even if the process A doesn't close the file descriptor (which is what seems to be the case here) and a process B appends to that file at some tome t0 + delta, then the process A would have to reopen the file descriptor to see the changes, it cannot hold to the same file descriptor and get new data being appended to that file... though it's obvious that what I've observed contradicts that assumption....

Clear contents of a file in Java using RandomAccessFile

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'.

Java : File get delete with Files.delete(path), when I try create same file name in next line it will create the old one(content will delete )

I have this code
Files.delete(Paths.get("a.txt"));
FileWriter f = new FileWriter("a.txt");
First line will delete file,
second line will create file but when i checked file created date it will give old one.
It is not because you declare a new instance of FileWriter that the underlying file is affected or even created in any ways.
According to the Javadoc, the constructor will throw an IOException in these cases (java 7)
IOException - if the named file exists but is a directory rather than a regular file, does not exist but cannot be created, or cannot be opened for any other reason
Try writing something in your file.
Also, you should be consistent and use Paths.get either in both statements or not at all. AFAIK Paths.get is filesystem dependent (in other words you may not be deleting the file that you are trying to recreate).

Write to External File without ending the program

I have a program that is only meant to be terminated by pressing Ctrl + C. In this program I write to an external file using:
File logFile = new File("output.txt");
PrintWriter log_file_writer = new PrintWriter(logFile);
log_file_writer.println("TEXT");
However because I don't know when the program will be terminated, I can't close the file using:
log_file_writer.close();
I think this is resulting in no text appearing in the output file.
Would anyone have a solution for this?
Thank you for your help.
log_file_writer.flush();
will push the content to disk
As the javadoc says:
PrintWriter(File file) Creates a new PrintWriter, without automatic line flushing, with the specified file.
Therefore, you need to flush the data you want to print that is actually buffered:
log_file_writer.flush();
You did not flush the content, I always use the autoFlush argument, but it is not available with File:
PrintWriter log_file_writer = new PrintWriter(new FileOutputStream("output.txt"),true);
but you can also use log_file_writer.flush(); after each write.

Categories

Resources