Write object toString() to file, formatted neatly in Java - java

I have a polymorphic HashSet that I want to write the toString() of each object in that HashSet to a file so that is is formatted the way it looks when printed to the console. I am able to write everything to the file, but each object is being printed out on one line. I would like to have each object printed the way it's toString() is formatted (every field printed on a new line).
Any help would be greatly appreciated. I have tried a bunch of things, but this is what I currently have for my method:
public void employeeWriter(String fileName, HashSet<Employee> employees)
{
try
{
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(fileName, false)));
for (Employee e : employees)
{
pw.println(e);
}
pw.close();
}
catch (IOException e)
{
System.err.println("Error writing to file in employeeWriter()");
e.printStackTrace();
}
}
Here is the Employee toString() - Every child of Employee has its own toString() method which prints this toString() plus its own unique fields.
#Override
public String toString()
{
String output = "\n\t--Employee--" + "\nName:" + "\t\t" + getName()
+ "\nTitle:" + "\t\t" + this.getClass().getSimpleName()
+ "\nID: " + "\t\t" + getId() + "\nHire Year:" + "\t\t"
+ getHireYear() + "\nTax Rate:" + "\t\t"
+ percentFormatter.format(getTaxRate()) + "\nPay Before Taxes:"
+ "\t" + formatter.format(getWeeklySalaryBeforeTaxes())
+ "\nPay After Taxes:" + "\t"
+ formatter.format(getWeeklySalaryAfterTaxes())
+ "\nWeekly Taxes:" + "\t\t"
+ formatter.format(getWeeklyTaxes());
return output;
}

In the toString method you are using \n as line separators. But if you open a file which uses Unix line separators in program that doesn't support them (eg. Notepad on Windows) the text will appear to be on one line.
The println method of FileWriter correctly uses platform-specific line separators, which is why your individual employee entries appear on separate lines but not the employee details from toString() method, because you are using fixed \n line separator there.
So one possible solution to this problem is using correct line separators for your platform in toString method (use System.lineSeparator() as suggested by Julian Ladisch).

Instead of \n use java.lang.System.lineSeparator(). That way it writes \r\n on windows platforms.

Related

Files.readAllLine() not working after FileWriting

hoping you're doing well, this is my first question
I have a trouble:
My goal is to create java files from pieces of code (fields, attributes, constructor)
I tried to do this by altering between reading and writing file.
Reading file to get the old value , delete closing "}"
Writing in file : the new piece of code, plus closing "}"
The problem with my try is that Files.readAllLine() or FileWriter() is not working.
You can find my source code below.
public static void fillFile(String fileName, String name, String value) throws IOException {
Path path = Paths.get(fileName);
List<String> all = Files.readAllLines(path,StandardCharsets.UTF_8);
System.out.println(" the path "+Paths.get(fileName));
System.out.println(name + " :; "+ value);
System.out.println("to write " + all.toString().replaceAll(", ", " ").substring(1, (all+"").replaceAll(", ", " ").length()-1) + "\n" + name + (name.endsWith(")")?"":" = ")+ value+ (name.endsWith(")")?"":";")+"\n } ddddddddddddddddddddddd");
FileWriter test = new FileWriter(fileName,true);
test.write(all.toString().replaceAll(", ", " ").substring(1, all.toString().replaceAll(", ", " ").length()-1) + "\n" + name + (name.endsWith(")")?"":" = ")+ value+ (name.endsWith(")")?"":";")+"\n }");
//test.flush();
test.close();
}
Another question : there is an other easy way to reach my goal ?
The solution is that the FileWriter classe should have a different path that the one which File.readAllLine()use.
So we have to create a temporary file, which will be copied to the desired fileName file, then we delete the temporary file
Hope this will help people who need it. It is working !!!
public static void fillFile(String fileName, String name, String value) throws IOException {
Path path = Paths.get(fileName);
List<String> all = null;
if (path.toFile().exists()) {
all = Files.readAllLines(path,StandardCharsets.UTF_8);}
if(all!= null) System.out.println(path + " the size of "+ all.toArray(new String[all.size()])+"");
Path path2 = Files.createTempFile(path.getParent(),"test-file", ".java");
Files.write(path2, ((all+"").replaceAll(", ", "\n").replaceAll("\\[", "").replaceAll("\\]", "").substring(1, ((all+"").replaceAll(", ", " ").replaceAll("\\[", "").replaceAll("\\]", "")).length()-1) + "\n" + name + value+ "\n" +"}").getBytes());
Files.copy(path2, path, StandardCopyOption.REPLACE_EXISTING);
Files.deleteIfExists(path2);
}

Java BufferedWriter issue

I've encountered this weird thing which prevents me from creating a new line in a .txt file, using a BufferedWriter connected to a FileWriter. However, if I save the file as the default option, .file. The spaces would be included in the document. The referred part of the code below:
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
for(Account acc : list) {
writer.write(acc.getFirst() + "," + acc.getLast() + "," + acc.getPassword() + "," + acc.getEmail() + "\n");
}
The values in the .write. method are all Strings.

Split strings with an "Enter"

I have code that splits a string into 3 strings, then prints them. I want each one to be separated by the equivalent of an "Enter". Here's the code:
String accval = text;
try {
PrintWriter writer = new PrintWriter(new BufferedWriter(
new FileWriter("sdcard/YS Data/Accelerometer.html",
true)));
String[] tempArr = accval.split("\\s+");
String x = tempArr[0] + "_"; //I want the enter to be where the underlines are:
String y = tempArr[1] + "_";
String z = tempArr[2] + "_";
for (String a : tempArr) {
writer.println("<h3 style=padding-left:20px;>" + x + y
+ z + "</h3><br>");
}
writer.flush();
writer.close();
} catch (IOException e) {
// put notification here later!!!
e.printStackTrace();
}
This outputs:
x=-0.125_y=0.9375_z=0.375
x=-0.125_y=0.9375_z=0.375
with the strings separated by underscores.
However, I want it to look like this:
x=-0.125
y=0.9375
z=0.375
x=-0.125
y=0.9375
z=0.375
Thanks for any help.
EDIT:
I've implemented the answer of #Julius in the following code that prints how I wanted it:
Code:
String accval = text;
try {
PrintWriter writer = new PrintWriter(new BufferedWriter(
new FileWriter("sdcard/YS Data/Accelerometer.html",
true)));
String[] tempArr = accval.split("\\s+");
String x = tempArr[0];
String y = tempArr[1];
String z = tempArr[2];
for (String a : tempArr) {
writer.println("<h3 style=padding-left:20px;>" + x + "<br>" + y + <br>
+ z + "</h3><br>");
}
writer.flush();
writer.close();
} catch (IOException e) {
// put notification here later!!!
e.printStackTrace();
}
Which prints:
x=0.25
y=125
z=1.23
x=0.125
y=725
z=0.935
if you want the line returns to be displayed in the browser, this is the way to go:
writer.println("<h3 style=padding-left:20px;>" + x + "<br/>" + y + "<br/>" + z + "<br/></h3>");
You can use
System.getProperty("line.separator")
to get a line separator.
You could explicitly write CR+LF as in the other answers here. You can also use the default line break by just using println separately for each item, e.g.:
for (String a : tempArr) {
writer.println("<h3 style=padding-left:20px;>");
writer.println(x);
writer.println(y);
writer.println(z);
writer.println("</h3><br>");
}
This is slightly more verbose but won't run into inconsistent line-break issues on systems where CRLF is not the default line ending.
Note, however, that the linebreaks in the HTML probably won't be rendered, unless your CSS specifies that they should be. You probably want to just write a "<br>" tag after each element instead of an actual line break, e.g.:
writer.println("<h3 style=padding-left:20px;>");
writer.println(x + "<br>");
writer.println(y + "<br>");
writer.println(z + "<br>");
writer.println("</h3><br>");
You wouldn't have to use println for this (you could use print or just concatenate as you were doing before), but it does make the generated source a bit more readable.
Off topic, your use of linebreaks in an "<h3>" header tag isn't really semantically appropriate. A "<div>" with appropriate styling would be a more accurate representation, unless these are actually serving as section headers.
"\r\n" is the correct string for a line break on Windows systems; "\n" is correct on Linux and other Unix-based systems. This will work on either type of system:
String newline = String.format("%n");
which will set newline to "\r\n" or "\n" as appropriate (or perhaps some other sequence on some OS's from a different planet :)
EDIT:%n by definition inserts System.getProperty("line.separator") as noted in another answer. So these are equivalent.

Write to the same file from different Methods [duplicate]

This question already has answers here:
Writing to an already existing file using FileWriter Java
(2 answers)
Closed 9 years ago.
I have been working with Files in Java. And I know the basics of reading and writing to/from files. Below is the code that I tried to write
void qlm(String option,String initiate,String ii,String file_path,String source,List destination){ //,String paths,String src){
String [] Ln = {"B","C","D"};
int count =1, counter=1,seq=1;
try{
System.out.println("Here: " +file_path);
PrintWriter pwr = new PrintWriter(new FileWriter(getHandleB()),true);
for(int i=0;i<Ln.length;i++){
pwr.println("Sequence_Number" + "|" + "QLM_Operation" + "|" + "II_D" + "|" + "Val_D" + "|" + "List" + "|" + "Type" + "|" + "Status" + "|" + "Source" + "|" + "Destination");
pwr.println(count + "|" + option + "|" + "DataK" + "|" + "Value" + "|" + Ln + "|" + "Null" + "|" + "Pending" + "|" + source + "|" + Ln[i]);
count++;
}
pwr.close();
getHandleB() is the path of the File. This is performed in the method qlm(parameters)
Now I want to write in the same File (path: getHandleB()) from a different method named handle(parameters)
The output of this function, should write in the same file without removing the contents of the previous method. When i try to write in the file, it removes the previous contents and writes the new one. How can I avoid this. I want all the contents from all the methods to be written. Thanks for all the help.
You are not appending to the File. Use the FileWriter constructor that allows for appending, that has a boolean/true as its second parameter.
PrintWriter pwr = new PrintWriter(new FileWriter(getHandleB(), true),true);
Edit
Separating out the constructor calls in my code above should help you to understand what's going:
FileWriter fileWriter = new FileWriter(getHandleB(), true);
PrintWriter pwr = new PrintWriter(fileWriter, true);
So you see that yes, there are two boolean parameters being used here, but they're being used with different constructors.
You need to use the appropriate FileWriter constructor with true as the second argument.
By default, a FileWriter truncates the file it opens.

java - Can't get "append mode" on Filewriter to work for me

I've been all over the search and it seems like the given answers just don't work for me.
My code is relatively simple, it generates an array of Objects, populates it with some random strings and then tries to output to a file. The idea is basically to generate a CSV file with some names, login names, passwords, etc. and the names are strings of random letters (long story, it's for mass-populating an environment with users...)
I have a "Writer" class like this:
public class Writer {
public static void log(String message) throws IOException {
PrintWriter out = new PrintWriter(new FileWriter("testlog.txt"), true);
out.println(message);
out.close();
}
}
And a loop like this:
for (int y=0; y < num_names; y++) {
try {
Writer.log(arrayTest[y].first + "," + arrayTest[y].last + "," + arrayTest[y].loginName + "," + arrayTest[y].password +
"," + arrayTest[y].email);
} catch (IOException ex) {
Logger.getLogger(Csvgenerator.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(arrayTest[y].first + "," + arrayTest[y].last + "," + arrayTest[y].loginName + "," + arrayTest[y].password +
"," + arrayTest[y].email);
}
My expectation is that I will loop through and for each object in arrayTest[] I output a single line of data to the file.
I included the System.out.println just for debugging.
When I run my code, the System.out.println proves that it works properly -- I get a list of 10 rows. (num_names = 10 here) so this proves that each time I get to this line of code, I have a unique "row" of data which gets printed out.
However, at the end of the run, the file "testlog.txt" only contains a single line -- the very last row in my output.
I've tried "out.append" instead of "out.println" but no difference. It appears as though every time I call the logger it's creating the file anew for some reason.
So in other words if my console output (from the system.out.println) looks like this:
nxoayISPaX,aNQWbAjvWE,nanqwbajvwe,P#ssw0rd!,nanqwbajvwe#mylab.com
RpZDZAovgv,QOfyNRtIAN,rqofynrtian,P#ssw0rd!,rqofynrtian#mylab.com
SajEwHhfZz,VziPeyXmAc,svzipeyxmac,P#ssw0rd!,svzipeyxmac#mylab.com
sifahXTtBx,MRmewORtGZ,smrmewortgz,P#ssw0rd!,smrmewortgz#mylab.com
PlepqHzAxE,MQUJsHgEgy,pmqujshgegy,P#ssw0rd!,pmqujshgegy#mylab.com
VKYjYGLCfV,nuRKBJUuxW,vnurkbjuuxw,P#ssw0rd!,vnurkbjuuxw#mylab.com
YgvgeWmomA,ysKLVSZvaI,yysklvszvai,P#ssw0rd!,yysklvszvai#mylab.com
feglvfOBUX,UTIPxdEriq,futipxderiq,P#ssw0rd!,futipxderiq#mylab.com
RAQPPNajxR,vzdIwzFHJY,rvzdiwzfhjy,P#ssw0rd!,rvzdiwzfhjy#mylab.com
DeXgVFClyg,IEuUuvdWph,dieuuuvdwph,P#ssw0rd!,dieuuuvdwph#mylab.com
Then testlog.txt only contains a single line:
DeXgVFClyg,IEuUuvdWph,dieuuuvdwph,P#ssw0rd!,dieuuuvdwph#mylab.com
How do I force this to keep using the same file and just append new lines?
On the constructor PrintWriter(Writer out, boolean autoFlush), the second boolean argument is actually for autoflush, not append mode.
I think you intended to use FileWriter(File file, boolean append) constructor instead, ie:
PrintWriter out = new PrintWriter(new FileWriter("testlog.txt", true));
instead of
PrintWriter out = new PrintWriter(new FileWriter("testlog.txt"), true);

Categories

Resources