EDIT: Fixed! Was overwriting file instead of appending to the file.
I seem to have a bit of a problem trying to use a PrintWriter to add a "header" to a log file before use, so that my program knows that it is not just a random text file. The field output_file refers to an argument taken by the logger initialization function to set the log file, whereas log_file is a static file field for the (global and static) logging class. After opening the log file to check for errors, there is no header. Using logging functions, also carried out by a PrintWriter, gives the correct output. Am I doing something wrong? (I know I am reinventing the wheel as a logging API already exists for Java, but I am working on a learning exercise.)
//After testing to make sure the file specified does not exist
log_file=output_file;
output_file.createNewFile();
PrintWriter pw=new PrintWriter(log_file);
pw.println("**[PROGRAM_NAME Log]**");
pw.flush();
pw.close();
isInitialized=true;
EDIT: The file is definitely writable, or the logger itself wouldn't work. Also, for those who were wondering, the code to log something is the following (Same general method as writing the header AKA new PrintWriter(log_file);)
PrintWriter pw = new PrintWriter(log_file);
pw.print("[INFO:] " + sdf.format(new Date())); //The variable sdf is a date formatter for timestamps.
pw.println(" " + message);
pw.close();
The documentation for PrintWriter says:
file - The file to use as the destination of this writer. If the file
exists then it will be truncated to zero size; otherwise, a new file
will be created. The output will be written to the file and is
buffered.
So every time you use new Printwriter(log_file), you are actually truncating the file, erasing everything in it, and starting fresh.
This means, of course, that as soon as you start logging, the header data gets erased.
If you want to append to the file, rather than erase it every time, you need to open a FileOutputStream with the append option, and open the PrintWriter on top of it.
try (
FileOutputStream os = new FileOutputStream(log_file, true);
PrintWriter pw = new PrintWriter(os);
) {
pw.println("Your log line here");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
(Note the use of try-with-resources to auto-close the file when work with it is done. Of course, you can just keep it opened until you finish logging. This is merely an example.).
Related
I'm trying to keep a log of http responses with writing them in a txt file.
I'm using the FileWriter in Java, but unfortunately when the number of lines (e.g. 1000 lines) or the size of the txt file (e.g. 80kb) is exceeded, it automatically removes the previous content and writes the new ones.
This happens every time the limit is exceeded.
try{
File file = new File("response.txt");
file.createNewFile();
FileWriter writer = new FileWriter(file,true);
writer.write(+System.currentTimeMillis()+"\t"+response+"\n");
writer.flush();
writer.close();}
catch(IOException ioe){
System.out.println("\nError");}
file.createNewFile();
Here you are creating a new file every time you call this method.
FileWriter writer = new FileWriter(file,true);
Here you are trying to append to an existing file, which no longer exists because of the prior File.createNewFile(). So you are losing all your prior output and writing to a new file every time you call this method. Remove it.
This kind of second-guessing is always and everywhere a complete waste of time and space. new FileWriter() already has to do all that anyway, and you're just forcing it to happen twice: in this case, erroneously.
In fact you should try to keep the file open rather than reopening and reclosing it every time you call this method. What you're doing is horrifically inefficient. As well as not working.
NB When you get an exception, print the exception. Not just "error". Otherwise next thing you know you will be asking here why it prints "error", just because you didn't write your code properly.
I am guessing it's either because:
There's not enough disk space.
file.createNewFile() is being used for every line and it's not reliable.
You open and close the stream for every line.
You call this code in a multithreaded environment without synchronising.
Try the following:
BufferedWriter out = null;
try
{
out = new BufferedWriter(new FileWriter(file, true));
out.append(response);
out.newLine();
} catch(Exception e)
{
e.printStackTrace(); // if needed
out.append("Error");
out.newLine();
}
finally
{
ResourceUtil.closeQuietly(out);
}
I'm using txt files, creating them with the class PrintWriter. This allows me to print inside a txt file some content using println(...) method.
But now I need to add some content at the end of the list that I created. Like this:
PrintWriter writer = new PrintWriter("File.txt", "UTF-8");
writer.println("Hello");
writer.println("Josh!");
writer.close();
the result is a file like this:
Hello
Josh!
but what if I would like to add new words at the bottom of the text? I would prefer an overwriting of the file "File.txt" with the content updated?
Hello
Josh!
How are you?
I was thinking on something like, "Ok I have to add another line at the end, so read all the file, and write another file (with the same name and content) adding a new line at the end", but it seems too strange to do, I feel like there is another simple way to do it. Any other idea?
You could simply use a FileWriter instead, it has an append mode that you can enable:
FileWriter writer = new FileWriter("File.txt");
writer.write("Hello\n");
writer.write("Josh!\n");
writer.close();
writer = new FileWriter("File.txt", true);
writer.append("Great!");
writer.close();
Your suspicions are correct.
You should use try with resources (Java 7+):
try(PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("File.txt", true)))) {
out.println("How are you?");
}catch (IOException e) {
//exception handling left as an exercise for the reader
}
The second parameter to the FileWriter constructor will tell it to append to the file (as opposed to clearing the file). Using a BufferedWriter is recommended for an expensive writer (i.e. a FileWriter), and using a PrintWriter gives you access to println syntax that you're probably used to from System.out. But the BufferedWriter and PrintWriter wrappers are not strictly necessary.
Also this allows you to append to a file, rather than replacing the whole file, on every run. Lastly, try with resources means you do not have to call .close(), it's done for you! Grabbed from here
I'm simply trying to add a new line of text to my *.txt file, but nothing happens at all. The file is packed with a .war, so I use a ClassLoader to access the file. Also, both my eclipse IDE, and the contents of the file, use UTF-8 encoding.
I've used these for inspiration:
How to add a new line of text to an existing file in Java?
Java BufferedWriter object with utf-8
Now my code is mainly based on the last post, and looks like this:
public class test {
public static void main(String[] args){
URL url = Thread.currentThread().getContextClassLoader().getResource("MilestoneExport.txt");
File file = new File(url.getFile());
System.out.println(file.canRead()); //true
System.out.println(file.canWrite()); //true
try {
BufferedWriter out = new BufferedWriter
(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
out.append("new line");
out.append("new line 2");
out.append("new line 3");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I've confirmed that the file is in fact found, and it reads fine. I've been able to output the entire content of it to the console through the use of a BufferedReader. The path of the file is also correct, but absolutely no text is added to the file. I've made sure that I have refreshed and updated every time I've run the program.
Also, I've tried to create a simple empty file called foo.txt, which is located in the same directory as test.java. I added the following code to the main method, as provided by the BufferedWriter API, at http://docs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html
PrintWriter out2 = new PrintWriter(
new BufferedWriter(new FileWriter("foo.txt")));
out2.println("new Line");
out2.close();
What am i missing here? Why are there no error messages, and no responses or feedbacks whatsoever?
EVERYTHING BELOW IS ONLY ADDITIONAL INFO ABOUT WHAT I'VE TRIED. NO FEEDBACK IN ANY CASES:
Not this one: Why is BufferedWriter not writing to file?
Not this one: why is bufferedwriter not writing in the file?
Not this one: Unable to write to file using BufferedWriter
Yet another "remember to close/flush": Java : Problems accessing and writing to file
Defining the BufferedWriter outside the try block makes no difference, but I tried it anyway, due to How to write detail into file using BufferedWriter and FileWriter in Java?
Also, this code, from this answer, does nothing as well...
try {
BufferedWriter output = new BufferedWriter(new FileWriter(new File("house.txt")));
output.write("text");
output.close();
}
catch (IOException e) {
e.printStackTrace();
}
last but not least, I suspected that it might have something to do with the packaging of my Web-App, and differences between the source and target-folders. So I copied the code to a brand new clean project, but it still does nothing at all...
EDIT:
this code:
System.out.println(file.exists());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
System.out.println(file.getName());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.setLastModified(new GregorianCalendar().getTimeInMillis()));
gives these outputs:
true
D:\Data\myworkspace\MyProject\target\classes\MilestoneExport.txt
D:\Data\myworkspace\MyProject\target\classes\MilestoneExport.txt
MilestoneExport.txt
false
true
true
Am I completely misunderstanding the use of java's File-objects, and it's uses with FileWriters? The file is clearly 100% confirmed the correct file.
You should use the other constructor of FileOutputStream in order to open the file in append mode :
FileOutputStream(File file, boolean append)
I.e,
new FileOutputStream(file, true)
Since I can't comment, you might not be saving the file back into the archive it came from (I'm not sure if java supports writing to the internal structures of archives by editing the files that are included, however you might want to try to store the file externally to the archive to see if that is the place the issue comes from).
The cause of what you posted in the comments is that your IDE won't extract the resource file from a compiled program, if you want to sync the internal data you might be able to setup a client-server connection using sockets and creating a program that writes the data to the local file from data packets send to your web-app, otherwise retrieving the edited file from where you are hosting might be less complicated (or if you are deploying from the same PC you might be able to get away with a symbolic or hard link)
I've tried this code that is very similar to yours and it's working nicely,
so i think the problem is the way you are picking the path of the file.
public static void main(String[] args){
File file = new File("./localtest.txt");
System.out.println(file.canRead()); //true
System.out.println(file.canWrite()); //true
try {
BufferedWriter out = new BufferedWriter
(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
out.append("new line");
out.append("new line 2");
out.append("new line 3");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
this works
PrintWriter pw= new PrintWriter(
new BufferedWriter(new FileWriter("C:\\foo.txt")));
pw.println("line 1");
pw.close();
I have a little doubt about following code:
try {
File file = new File("writing");
file.createNewFile();
System.out.println(file.delete());
System.out.println(file.exists());
PrintWriter pw = new PrintWriter(file);
pw.print(324.2342);
pw.flush();
pw.close();
FileReader fr = new FileReader(file);
BufferedReader br = new BufferedReader(fr);
System.out.println(br.readLine());
br.close();
} catch(IOException ioE) {
System.out.println("Indeed");
}
Why in this circumstance the method file.delete() apparently says that it works as it returns "true" when executed and it gets also confirmed by the file.exists() method which returns "false". However at runtime I do not get any exception like "IOException the file "writing" does not exist" or something likewise.
Why does the file keep staying in the heap even though deleted physically? Shouldn't it be automatically garbage collected as soon as the delete method gets called? I know it does not because I saw the output.
This is because the File represents a abstract path, see the JavaDoc for it http://docs.oracle.com/javase/6/docs/api/java/io/File.html. It does not represent a file handle in the OS.
The line in your code:
PrintWriter pw = new PrintWriter(file);
Simply creates a new file. Try deleting the file after calling this...
File object represents a path to a physical file on the file system either exists or not. That's why you have exists() (to check if it exists) and createNewFile() (to create the file if it is not found).
Also note that PrintWriter(File file) creates a new file if it does not exist.
Parameters:
file - The file to use as the destination of this writer. If the file
exists then it will be truncated to zero size; otherwise, a new file
will be created. The output will be written to the file and is
buffered.
The File is handle to real file (that exists or not). You create and then delete the file above, as you say - all good so far.
When you come to the PrintWriter later on it creates the file once more when you use it - it doesnt matter that you deleted it before.
In fact depending on your use case this might be exaclty wht you want - you may want to delete an old log file for example before re-createing and writing to it once more.
Finally, nothing in your code will be eligible for garbage collection until your method exist, and even then the underyling file will continue to exist (if you dont delete it agin) - and any garbage colleciton in this case wouldnt effect the underlying file. It'll be deleted after the delete invokation and exist again once youre PrintWriter is done with it.
Hope this helps!
The file doesn't have a link to a particular file, rather to any file pointer by the file's path. With this line you're creating a new file:
PrintWriter pw = new PrintWriter(file);
I actually checked other posts that could be related to this and I couldn't find any answer to my question. So, had to create this newly:
The file does not get created in the given location with this code:
File as = new File ("C:\\Documents and Settings\\<user>\\Desktop\\demo1\\One.xls");
if (!as.exists()) {
as.createNewFile();
}
FileOutputStream fod = new FileOutputStream(as);
BufferedOutputStream dob = new BufferedOutputStream(fod);
byte[] asd = {65, 22, 123};
byte a1 = 87;
dob.write(asd);
dob.write(a1);
dob.flush();
if (dob!=null){
dob.close();
}
if(fod!=null){
fod.close();
The code runs fine and I don't get any FileNotFoundException!!
Is there anything that I'm missing out here?
You can rewrite your code like this:
BufferedOutputStream dob = null;
try {
File file = new File("C:\\Documents and Settings\\<user>\\Desktop\\demo1\\One.xls");
System.out.println("file created:" + file.exists());
FileOutputStream fod = new FileOutputStream(file);
System.out.println("file created:" + file.exists());
BufferedOutputStream dob = new BufferedOutputStream(fod);
byte[] asd = {65, 22, 123};
byte a1 = 87;
dob.write(asd);
dob.write(a1);
//dob.flush();
}
catch (Exception ex) {
ex.printStackTrace();
}
finally {
if (dob != null) {
dob.close();
}
}
In this case it is only necessary to call the topmost stream handler close() method - the BufferedOutputStream's one:
Closes this output stream and releases any system resources associated with the stream.
The close method of FilterOutputStream calls its flush method, and then calls the close method of its underlying output stream.
so, the dob.flush() in try block is commented out because the dob.close() line in the finally block flushes the stream. Also, it releases the system resources (e.g. "closes the file") as stated in the apidoc quote above. Using the finally block is a good practice:
The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.
The FileOutputStream constructor creates an empty file on the disk:
Creates a file output stream to write to the file represented by the specified File object. A new FileDescriptor object is created to represent this file connection.
First, if there is a security manager, its checkWrite method is called with the path represented by the file argument as its argument.
If the 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 then a FileNotFoundException is thrown.
Where a FileDescriptor is:
Instances of the file descriptor class serve as an opaque handle to the underlying machine-specific structure representing an open file, an open socket, or another source or sink of bytes. The main practical use for a file descriptor is to create a FileInputStream or FileOutputStream to contain it.
Applications should not create their own file descriptors.
This code should either produce a file or throw an exception. You have even confirmed that no conditions for throwing exception are met, e.g. you are replacing the string and the demo1 directory exists. Please, rewrite this to a new empty file and run.
If it still behaving the same, unless I have missed something this might be a bug. In that case, add this line to the code and post output:
System.out.println(System.getProperty("java.vendor")+" "+System.getProperty("java.version"));
Judging from the path, I'd say you are using Win 7, am I right? What version?
Then it means there is a file already in your directory