Reputation: 673
I have a simple project where I created a Store with customers, products and employees. Each is represented by a Class of course and I also have a CSV file for each one of them to be able to load data from and save data to it.
I'm facing issues where the file reading/writing is working, but not really. For example, I have the ability to save each file individually so if for instance I want to create a new customer, I'd save it to the list and then to the file. Issue is, once I do it for another Class (i.e if I create a new employee) and then save it again, the customer file object I saw in the CSV earlier is deleted. BUT, once I add a new object again, that same object reappears again. Hope you can somehow understand, but here is a more detailed view:
customer.csv
is empty:
Me creating a new customer:
Created and saved to CSV:
Now, if I go to the other menu, and click on "Save all data" that jon snow
customer object will be gone. Then if I create a new customer, then it will be added to the CSV file, along with the jon snow
I added earlier. So why is it gone in the first place?
So here is the whole file reader/writer code I'm using:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.ArrayList;
import java.io.IOException;
import java.util.List;
import java.util.Scanner;
class CSV {
static void CreateFile(String filename) { //Create new file
try {
File fileToCreate = new File(filename);
if (fileToCreate.createNewFile()) {
System.out.println("File created sucessfully: " + fileToCreate.getName());
}
} catch (IOException e) {
System.out.println("Cannot create file!");
}
}
static void ReadFile(String path_and_filename){
try {
File fileToRead = new File(path_and_filename);
Scanner myReader = new Scanner(fileToRead);
System.out.println("Reading file "+path_and_filename+" :");
while (myReader.hasNextLine()) {
String data = myReader.nextLine();
System.out.println(data);
}
myReader.close();
System.out.println();
} catch (FileNotFoundException e) {
System.out.println("There is no such file "+"\"path_and_filename\""+".\n");
}
}
// The StringBuilder in Java represents a mutable sequence of characters.
// Java's built in String class is not mutable.
static void saveArrayListToFile(List<Output> listToSave, String fileName, String sep) throws Exception {
StringBuilder ans = new StringBuilder();
for (Output record : listToSave) {
ans.append(record.createOutput());
ans.append(sep);
}
saveStringToFile(ans.toString(), fileName);
System.out.println("\nData saved to "+ fileName);
}
static void saveArrayListToFile1(ArrayList<String> listToSave, String fileName, String sep){
StringBuilder ans = new StringBuilder();
for (Object record : listToSave) {
ans.append(record.toString());
ans.append(sep);
}
saveStringToFile(ans.toString(), fileName);
System.out.println("\nList was saved to file "+fileName+"\n");
}
static void saveStringToFile(String data, String fileName){
BufferedWriter bufferedWriter=null;
try {
bufferedWriter = new BufferedWriter(
new FileWriter(fileName,false));
bufferedWriter.write(data);
} catch (IOException e) {
System.out.println("Cannot write to file");
} finally {
try {
bufferedWriter.close();
} catch (IOException e) {
System.out.println("Cannot write to file");
}
}
}
}
When I'm creating a new customer, I call it from a menu and it looks like this:
switch (selection) {
case 1:
try {
System.out.println("You're registering as a new customer");
String custID = ObjectIDs.generateID();
System.out.println("Enter first name:");
String firstName = sc.next();
System.out.println("Enter last name:");
String lastName = sc.next();
st.newCustomer(custID, firstName, lastName);
st.saveCustomersList();
} catch (Exception e) {
e.printStackTrace();
}
break;
the saveCustomerList()
function is this:
@SuppressWarnings("unchecked")
void saveCustomersList() throws Exception {
CSV.saveArrayListToFile((List<Output>)(List<?>) customers, CUSTOMERS_FILE_PATH,"\n");
}
And then the functions calls saveArrayListToFile()
to save it.
The behavior is the same with Product and Employee projects, so I randomly chose to show how it acts when creating a new Product.
I hope I added enough information. If needed, I can paste more code in but I already feel it's very cluttered. Hopefully it's ok.
Thank you very much :)
Upvotes: 0
Views: 66
Reputation: 446
In addition to pafau k. I would like to add some things at least I would do differently...
First of all:
Everything below is in saveStringToFile
bufferedWriter = new BufferedWriter(new FileWriter(filename, true));
This puts the File into appending mode (if you want to append to a file you can also get rid of the boolean (second argument) entirely because appending is standard: new FileWriter(filename)
)If for some case the Creation of the BufferedWriter failed you will still have a null-pointing object as bufferedWriter
. This however means that you will be surprised with a NullPointerException in your finally block. To prevent this first of all do a check in your finally block:
if (bufferedWriter != null) {
// Close your bufferedWriter in here
}
Also, if you run into an error you will likely be presented with the same error message twice.
Now cosmetics:
public static void createFile()
for example or static void readFile()
String thisIsAVeryLongVariableWithALotOfSeperations = "Foo";
The generic types in saveArrayListToFile1() work like a placeholder. So you declare ArrayList<String> listToSave
so you don't need a cast in the following for-loop: You can simply write:
for (String record : listToSave) {
ans.append(record);
ans.append(sep);
}
I hope this fixes all errors or complications. :)
Upvotes: 0
Reputation: 1687
At the moment it's hard to say, as one can only hypothesise as to what happens when you click on "Save all data". There are some weird things (what is saveArrayListToFile
and saveArrayListToFile11
? Why does one declare an exception? When are these called?).
Having said that, look at the actual file writing method saveStringToFile
, it says:
bufferedWriter = new BufferedWriter(new FileWriter(fileName,false));
This false
there means 'do not append to file, rewrite it from scratch'. So each time you call it, file contents are discarded and replaced from what you provide to the method call. So my somewhat educated guess would be:
But it's all guessing. Try creating a minimal, reproducible example
Upvotes: 2