I'm currently stuck on a spot in my code. I need to write data to a text file, I have sorts going and they are taking the time that each sort takes to complete and then puts them into a txt file that I can then use to create graphs. Problem is that I just get one line after I run the program. I can't get it to keep each result.
public static void resultsToFile(String sort, double seconds, File file)
{
try (PrintWriter out = new PrintWriter(new FileWriter(file)))
{
out.write(sort + "\t");
out.write(seconds + " seconds\n");
out.flush();
out.close();
}catch (IOException e)
{
e.printStackTrace();
}
}
This is what I have so far for my writing to files method. Any help would be greatly appreciated!
You're creating a new PrintWriter object each time you write a line of results to the file and thus over-writing any previously existing File that held the previous line of data. Why not create your PrintWriter once in the class, and then close it when you're done writing all of the data to file?
As HovercraftFullOfEals mentioned, you open the file for each line, and this is a big performance overhead.
Yet the problem you see is because you don't open the file to append to it, but to write to it from the beginning. To append to the file, open it using the constructor FileWriter(File,boolean):
try (PrintWriter out = new PrintWriter(new FileWriter(file, true)))
Related
I'll post my code first:
private void validateXml(String xml) throws BadSyntaxException{
File xmlFile = new File(xml);
try {
JaxbCommon.unmarshalFile(xml, Gen.class);
} catch (JAXBException jxe) {
logger.error("JAXBException loading " + xml);
String xmlPath = xmlFile.getAbsolutePath();
System.out.println(xmlFile.delete()); // prints false, meaning cannot be deleted
xmlFile.delete();
throw new BadSyntaxException(xmlPath + "/package.xml");
} catch (FileNotFoundException fne) {
logger.error("FileNotFoundException loading " + xml + " not found");
fne.printStackTrace();
}
}
You can see in my comment where I print that the file cannot be deleted. Files can't be deleted from a try/catch? So, if there is a file with bad xml syntax, I want to delete the file in the catch.
EDIT: I can delete the file when I use delete() from outside of this function. I am on Windows.
Make sure that this method invocation JaxbCommon.unmarshalFile(xml, Gen.class); closes any stream when the exception occurs. If the stream that was reading the file is left opened then you cannot delete it.
The problem is unrelated to the try/catch. Do you have permissions to delete the file?
If you are using Java 7 you can use the Files.delete(Path) which I think will actually throw an IOException with the reason why you can't delete the file.
There is no general restriction regarding the use of java.io.File.delete() on try/catch blocks.
The behavior of many java.io.File methods can depend on platform/enviroment that the application is running. It is because they can need to access file system resources.
For example, the following code returns false on Windows 7 and true on Ubuntu 12.04:
public static void main(String[] args) throws Exception {
File fileToBeDeleted = new File("test.txt");
// just creates a simple file on the file system
PrintWriter fout = new PrintWriter(fileToBeDeleted);
fout.println("Hello");
fout.close();
// opens the created file and does not close it
BufferedReader fin = new BufferedReader(new FileReader(fileToBeDeleted));
fin.read();
// try to delete the file
System.out.println(fileToBeDeleted.delete());
fin.close();
}
So, the real problem can depend on several factors. However, it is not related to the code residing on a try/catch block.
Maybe, the resource that you is trying to delete was opened and not closed or locked by another process.
I have a file of 250 line. I wanted to insert some text after line 128.
I only found that I can append a text at the end of file
like
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("outfilename", true)));
out.println("the text");
out.close();
} catch (IOException e) {
//oh noes!
}
That is found on this post How to append text to an existing file in Java
But with no mention to the line number or sth.
There's no way to insert text in the middle of a file because of how file systems work. They implement operations to modify the data blocks of a file and to add and remove blocks from the end of a file. What they don't implement is adding or removing data blocks anywhere else because of inherent complexities of these operations.
What you have to do is copy the first 125 lines to a new file, add what you want to add, and then copy the rest of the file. If you want to you can then rename the new file as the old file so you don't accumulate temporary files.
You can read the original file and write the content in a temp file with new line inserted. Then, delete the original file and rename the temp file to the original file name.
The following code can help you to insert a given string at a given position in an existing file:
public static void writeStrToFileAtGivenLineNum(String str, File file, int lineNum) throws IOException {
List<String> lines = java.nio.file.Files.readAllLines(file.toPath());
lines.add(lineNum, str);
java.nio.file.Files.write(file.toPath(), lines);
}
I use this simple code to write a few strings to the file called "example.csv", but each time I run the program, it overwrites the existing data in the file. Is there any way to append the text to it?
void setup(){
PrintWriter output = createWriter ("example.csv");
output.println("a;b;c;this;that ");
output.flush();
output.close();
}
import java.io.BufferedWriter;
import java.io.FileWriter;
String outFilename = "out.txt";
void setup(){
// Write some text to the file
for(int i=0; i<10; i++){
appendTextToFile(outFilename, "Text " + i);
}
}
/**
* Appends text to the end of a text file located in the data directory,
* creates the file if it does not exist.
* Can be used for big files with lots of rows,
* existing lines will not be rewritten
*/
void appendTextToFile(String filename, String text){
File f = new File(dataPath(filename));
if(!f.exists()){
createFile(f);
}
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f, true)));
out.println(text);
out.close();
}catch (IOException e){
e.printStackTrace();
}
}
/**
* Creates a new file including all subfolders
*/
void createFile(File f){
File parentDir = f.getParentFile();
try{
parentDir.mkdirs();
f.createNewFile();
}catch(Exception e){
e.printStackTrace();
}
}
You have to use a FileWriter (pure Java (6 or 7)) rather than PrintWriter from the Processing API.
FileWriter has a second argument in it's constructor that allows you to set a Boolean to decide whether you will append the output or overwrite it (true is to append, false is to overwrite).
The documentation is here: http://docs.oracle.com/javase/7/docs/api/java/io/FileWriter.html
Note you can also use a BufferedWriter, and pass it a FileWriter in the constructor if that helps at all (but I dont think it's necessary in your case).
Example:
try {
FileWriter output = new FileWriter("example.csv",true); //the true will append the new data
output.println("a;b;c;this;that ");
output.flush();
output.close();
}
catch(IOException e) {
println("It Broke :/");
e.printStackTrace();
}
As above, this will work in the PDE - and in Android - but if you need to use it in PJS, PyProcessing, etc, then you will have to hack it
dynamically read the length of the existing file and store it in an ArrayList
add a new line to the ArrayList
use the ArrayList index to control where in the file you are currently writing
If you want to suggest an enhancement to the PrintWriter API (which is probably based off of FileWriter), you can do so at Processing's Issue page on GitHub:
https://github.com/processing/processing/issues?state=open
Read in the file's data, append your new data to that, and write the appended data back to the file. Sadly, Processing has no true "append" mode for file writing.
I want to write data to a text file. But, in my application, i will want to keep on writing items to the text file (Which means, the text that i want to write, should be appended to the file - and not create a new file every time)
My code, is as follows; But how could i append text the next time i am writing something to the file ?
1.) The problem with the code below is, the first time writes to the file, but when i am trying to write for the 2nd time i get the following exception;
java.io.IOException: Stream closed
2.) I want to be able to write to the same file untill the application is closed. Therefore, how can i close the Stream when the application is closed ?
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class WriteToFileExample {
public void writeToFile(String stuff) {
try {
File file = new File("../somefile.txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(stuff);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
UPDATE 1
private File file;
public WriteToFileExample(){
file = new File("../somefile.txt");
}
public void writeToFile(String stuff) {
try {
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(stuff);
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
EXCEPTION
Exception in thread "main" java.lang.NullPointerException
at com.proj.example.Log.WriteToFile(WriteToFileExample.java:3)
Which points to if (!file.exists()) {.
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
Use the true argument for the FileWriter constructor.
You should create your FileWriter using the contructor that takes an extra boolean argument, that indicates that you want to append.
FileWriter fw = new FileWriter(file.getAbsoluteFile(), true);
You never close the FileWriter in your code. And from the documentation for the class:
Whether or not a file is available or may be created depends upon the
underlying platform. Some platforms, in particular, allow a file to be
opened for writing by only one FileWriter (or other file-writing
object) at a time. In such situations the constructors in this class
will fail if the file involved is already open.
Close the file writer before exiting your method, its good practice anyway. And yes, definitely do open the writer in append mode, if you don't want the files contents to be blown away every time you call your method.
Checking the api, says that the FileWriter constructor takes a boolean to flag whether to append or not. That answer your question?
Instead of doing this:
FileWriter fw = new FileWriter(file.getAbsoluteFile());
do as follow:
FileWriter fw = new FileWriter(file.getAbsoluteFile(),true);
As to append on a existing file FileWriter needs an extra argument as true here
FileWriter
public FileWriter(File file, boolean append) throws IOException
Constructs a FileWriter object given a File object. If the second argument is true, then bytes will be
written to the end of the file rather than the beginning.
Parameters:
file - a File object to write to
append - if true, then bytes will be
written to the end of the file rather than the beginning
Throws:
IOException - 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
Since:
1.4
I've been working on sort of "logging" to text file using BufferedWriter and I came across a problem:
I run the following code.. fairly basic..
BufferedWriter out = new BufferedWriter(new FileWriter(path+fileName));
String str = "blabla";
out.write(str);
out.close();
and the next thing I know is that the entire file that had couple of lines of text has been cleared and only 'blabla' is there.
What class should I use to make it add a new line, with the text 'blabla', without having to get the entire file text to a string and adding it to 'str' before 'blabla'?
What class should I use to make it add a new line, with the text 'blabla', without having to get the entire file text to a string and adding it to 'str' before 'blabla'?
You're using the right classes (well, maybe - see below) - you just didn't check the construction options. You want the FileWriter(String, boolean) constructor overload, where the second parameter determines whether or not to append to the existing file.
However:
I'd recommend against FileWriter in general anyway, as you can't specify the encoding. Annoying as it is, it's better to use FileOutputStream and wrap it in an OutputStreamWriter with the right encoding.
Rather than using path + fileName to combine a directory and a filename, use File:
new File(path, fileName);
That lets the core libraries deal with different directory separators etc.
Make sure you close your output using a finally block (so that you clean up even if an exception is thrown), or a "try-with-resources" block if you're using Java 7.
So putting it all together, I'd use:
String encoding = "UTF-8"; // Or use a Charset
File file = new File(path, fileName);
BufferedWriter out = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file, true), encoding));
try {
out.write(...);
} finally {
out.close()'
}
Try using FileWriter(filename, append) where append is true.
try {
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("outfilename", true)));
out.println("the text");
out.close();
} catch (IOException e) {
//oh noes!
}
The above should work: Source Reference