Why is my attempt to append text to a file not responding? - java

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();

Related

Is there a line limit when writing to a txt file using Java?

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);
}

PrintWriter--No Output?

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

Best strategy to add lines of text to a text file

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

Unable to write a file while using Tomcat

I am unable to create and then write a file in Tomcat. The file gets created if I run the java program (only the writing piece of code) as a Java application, but fails in Tomcat.
there is no error message. The file is simply not created at all!
Please suggest if I am missing something here:
//code inside the servlet
public void setData(HttpServletRequest request){
name=request.getParameter("name");
address=request.getParameter("address");
BufferedWriter dataOut;
try {
System.out.println("Wrinting file...");
dataOut = new BufferedWriter(new FileWriter("data.txt", true));
dataOut.write("name:");
dataOut.flush();
dataOut.write("address");
dataOut.flush();
dataOut.write("\n");
dataOut.flush();
dataOut.close();
System.out.println("File write complete!");
}
catch(Exception e){
e.printStackTrace();
}
Looks like the file really is created without problems.
You may actually be missing where it is saved.
Change this line:
System.out.println("File write complete!");
To:
System.out.println("File write complete! Saved to: "+new File("data.txt").getAbsolutePath());
And you may solve the mistery.
The file is being created, but it is using a relative path. It will be created relative to the execution location, which on Tomcat will not be where you're used to it being.
Use an absolute path or print its location.

File deletion with delete() method in Java

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);

Categories