How to write into a single file through multiple classes in Java? - java

I am trying to write into a single text file through different classes.
I opened the text file from the main class:
public static void main( String[] args ) throws Exception {
BufferedWriter writer = new BufferedWriter(new FileWriter("src/t1.txt"));
Parser.getParseTree().print(); // where I called the method
writer.close();
}
This is a print() method from another class:
public static void print() throws IOException {
BufferedWriter writer = new BufferedWriter(new FileWriter("src/t1.txt"));
writer.write("afcad fad fad");
}
The BufferedWriter writer = new BufferedWriter(new FileWriter("src/t1.txt"));in print() method does not work and nothing prints into the t1.txt
file.

Don't have multiple places (methods) that each write to the file on their own.
Simply use one central place that opens the file for writing (probably using try-with-resource) and have any other code call a method at that central place. In other words, all your code should just invoke the same method!

Related

Java: Writing Text to a File from Multiple Methods in a Class WITHOUT a main() Method

I am currently dead in the water with a Java programming problem that seemed somewhat simple at first to do! I am trying to write text to a file from MULTIPLE methods in a class that does NOT contain a main() method, unlike other answers of this type question have used.
So... A quick outline of what my program is currently doing:
My program has one class (with the main() method obviously) that reads a text file stored on the disk, and passes sections of the text to certain methods in another class (second file in the project) to simply write the passed text to a text file. Each method in the class without the main() method needs to write the string passed to them to THE SAME file.
Why am I having trouble? I can easily write text to a file from ONE method in the class without the main() with FileWriter, but in order to have all of my other methods to write to the same file, I would need to make FileWriter global. I have tried to make it global, but then when I save text after another method saved text, it just rewrites the file to the latest text written.
My current class without the main() method:
package ADIFTOCSV;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class createADIF {
static File file;
static FileWriter fw;
static BufferedWriter writer;
static void init() throws IOException {
file = new File("/Users/Colin/Desktop/Myadif.txt");
fw = new FileWriter(file.getAbsoluteFile());
writer = new BufferedWriter(fw);
}
static void storeDate(String datez) throws IOException {
writer.write("<QSO_DATE:" + datez.length() + ">" + datez); <<----NULL POINTER EXCEPTION
}
static void storeFreq(String freqz) throws IOException {
writer.write("<FREQ:" + freqz.length() + ">" + freqz);
writer.close();
}
static void storeMode(String modez) {
}
static void storeBand(String bandz) {
}
static void storePower(String pwrz) {
}
static void storeTime(String timez) {
}
static void storeCall(String callz) {
}
static void storeRstSent(String rstsentz) {
}
static void storeRstRcvd(String rstrcvdz) {
}
static void storeComments(String commentsz) {
}
}
Each of these methods needs to write the String passed to them to the SAME file.
storeDate() is the first method to be called, therefore it writes text to the file first. However, when storeFreq() is called, it's text completely replaces the text written by storeDate(). This is obvious because I am forced to create a new FileWriter object in each method in order to write text. I cannot put FileWriter fw = new FileWriter(file.getAbsoluteFile()); outside the method to make it global; errors arise.
Am I missing something? Help is much appreciated. If any questions arise, or clarification is needed, please just ask!
You have to create the writer outside the methods.
Just defining the file outside is not enough.
If you recreate a writer to the same file in each method, of course it will overwrite.
The File instance is just a pointer to the file.
The writer is the "actual handle" that you need to reuse.
And be aware that you have to close the writer if you are finished with writing.
I would suggest that you scrap the class with the static methods and instead create a normal "File Write Handler" class which has a constructor where you can pass the File and writer to intialize the file writing classes and let that class handle all the writing to the file such that you can call a method like this:
FileWriteHandler.writer("<FREQ:" + freqz.length() + ">" + freqz);
and soforth for the rest you want printed. And finally call
FileWriteHandler.close();
Would be much cleaner and you could even make an interface for that class such that you can replace the FileWriterHandler with f.ex. a DatabaseWriteHandler or something like that.

Create a function that takes an Arraylist of any type?

I had a programming assignment where i had to save separate files, one a log file and the other a dat file. Each one took an arraylist object and saved it in the file but each arraylist was different. I was under a time crunch so i ended up making separate functions for both but i'm wondering if there's a more modular way of doing it. So for example:
public void saveLog (ArrayList<A> objectArray, File fileName) throws IOException {
if (!fileName.exists()) {
logFile.createNewFile();
}
FileOutputStream fileoutput = new FileOutputStream(fileName);
ObjectOutputStream output = new ObjectOutputStream(fileoutput);
output.writeObject(objectArray);
output.close();
fileoutput.close();
}
Is there a way to recode this so it will also take ArrayList"<"B">" ? I tried using ArrayList"<"Object">" but that threw an error. Very new to java so sorry if this seems like a simple question.
Basically you need to accept an ArrayList which contains objects that can be serialized, this can easily be expressed with a wildcard, eg:
public void saveLog(ArrayList<? extends Serializable> objectArray, File fileName) {
..
}
Which means "accept an ArrayList of an unspecified type which implements Serializable interface", which is a requirement for the ObjectOutputStream.
You could make the method generic on A (and I would prefer the List interface). Also, I would prefer a try-with-resources Statement. Like
public <A> void saveLog(List<A> objectArray, File fileName)
throws IOException {
if (!fileName.exists()) {
logFile.createNewFile();
}
try (FileOutputStream fileoutput = new FileOutputStream(fileName);
ObjectOutputStream output = new ObjectOutputStream(fileoutput)) {
output.writeObject(objectArray);
}
}

BufferedWriter keeps erasing what I wrote

I have the following class:
public class test{
private static final File testfile = new File("filename")//imaginary file name
private static BufferedWriter writer = null;
public void test1(){
writer = new OutStreamWriter(newFileOutputStream(testfile));
writer.write("hello");
writer.close();
}
public void test2(){
writer = new OutStreamWriter(newFileOutputStream(testfile));
writer.write("hello");
writer.close();
}
}
I want both of them to write to the same file whenever called and I create bufferedwriters inside each of the methods. However, once i call close on to the buffered writer, it cannot be opened again. How do I avoid this so I can call both methods multiple times?
I believe you had the same issue of this poster Java - Do not overwrite with bufferedwriter
Sanjay T. Sharma says:
"FileWriter takes an optional boolean argument which specifies whether it should append to or overwrite the existing content. Pass in true if you want to open the file for writing in append mode."

junit test when a method is called from one test

public void createRootElement() throws FileNotFoundException, IOException
{
Properties prop = new Properties();
prop.load(new FileInputStream("/home/asdf/Desktop/test.properties"));
File file = new File(prop.getProperty("filefromroot"));
try
{
// if file doesn't exists, then create it
if (!file.exists())
{
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write("<root>"); //create the root tag for the XML File.
bw.close();
}
catch(Exception e)
{
writeLog(e.getMessage(),false);
}
}
I'm new to junit testing.I would like to know how to write test case for this and what all to be considered. how to call the method is called from this test.?
A JUnit Test Case should look like this:
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class ClassToBeTestedTest {
#Test
public void test() {
ClassToBeTested c = new ClassToBeTested();
c.createRootElement();
assertTrue(c.rootElementExists());
}
}
You mark the test method with the #Test annotation and write the code that executes what you want to test.
At this example, I created a instance of your class and called the createRootElement method.
After that, I made a assertion to verify if everything behaved like I expected.
There are many things you can assert. Read the JUnit documentation for more information.
A good practice is to write the test BEFORE you actually write the code. So the test will guide you on how to write a better code. This is called TDD. Google for it.

Files clearing themselves upon object creation

I am having an annoying problem that I cannot seem to fix. I have a class named DirFormMgmt which manages two files; directories.txt and formats.txt. The problem is that when I instantiate an instance of this class when the program starts it clears everything that was in the files before it started, so for instance if I open the formats.txt file and type in ".avi" and run the program the text file will become blank. Here is the only code I have running in my class to isolate the issue and I am unsure of why this is happening:
At the top of my class I declare:
File dirFile = new File("directories.txt");
File formatFile = new File("formats.txt");
private BufferedReader dirReader;
private BufferedWriter dirWriter;
private BufferedReader formatReader;
private BufferedWriter formatWriter;
The constructor:
public DirFormMgmt() throws IOException {
checkFileExistence();
initReaderWriter();
}
The two methods called by the constructor:
public void checkFileExistence() throws IOException {
if (!dirFile.exists()) {
dirFile.createNewFile();
}
if (!formatFile.exists()) {
formatFile.createNewFile();
}
}
and:
public void initReaderWriter() throws IOException {
dirReader = new BufferedReader(new FileReader(dirFile));
dirWriter = new BufferedWriter(new FileWriter(dirFile));
formatReader = new BufferedReader(new FileReader(formatFile));
formatWriter = new BufferedWriter(new FileWriter(formatFile));
}
I checked to see if the createNewFile() methods were being called but they were not, so the problem must be with my initReaderWriter() method, but I am unsure of what is wrong, any help is greatly appreciated!
Use new FileWriter(file, true) to append content to an existing file. Otherwise, the contents will be overwritten.
You can't read and write to the same file like this. The FileWriter constructor is used to write to a file and replace all its contents.
EIther read everything in memory, and then write to the file, or write to another temp file, and remove the original file and rename the temp file when you're done.

Categories