Appending in Serialization - java

So far I have found that there is a way to do appending in serialization by making a sub-class but that seems like a lengthy way. Is there any better way to do appending in serialization?
I have this vectorlist in a class named Course
private Vector<Student> StudentList = new Vector<>();
I have 2 objects of course.
3 students are enrolled in 1 course and 2 students are enrolled in another. Now I call this method which is doing serialization in the file but when I call it with my 2nd course object, it replaces previous content.
public void Serialization() {
try {
File file = new File("EnrolledStudentsSerial.txt");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fo = new FileOutputStream(file);
ObjectOutputStream output = new ObjectOutputStream(fo);
output.writeObject("Course: " + this.name + "\n\nEnrolled Students: ");
for (int i = 0; i < StudentList.size(); i++) {
Student p_obj = StudentList.elementAt(i);
String content = "\n\tStudent Name: " + p_obj.getName() + "\n\tStudent Department: " + p_obj.getDepartment() + "\n\tStudent Age: " + p_obj.getAge() + "\n";
output.writeObject(content);
}
output.writeObject("\n");
fo.close();
} catch (IOException ioe){
System.out.println("Error: " + ioe.getMessage());
}
}

If you want to append to a file, instead of replacing the content, you need to tell the FileOutputStream that, by adding an extra argument and call FileOutputStream(File file, boolean append). FYI: don't do that with an ObjectOutputStream.
You don't need to call createNewFile(), since FileOutputStream will do that, whether appending or not.
However, you are not actually serializing your objects, since you're serializing strings instead. What you're doing makes no sense. Since you seem to want the result to be a text file (you're writing text, and file is names .txt), you should forget about ObjectOutputStream, and use a FileWriter instead.
Better yet, instead of using the old File I/O API, you should be using the "newer" NIO.2 API that was added in Java 7. You should also be using try-with-resources. Same goes for the ancient Vector class, which was replaced by ArrayList in Java 1.2.
Java naming convention is for field and method names to start with lowercase letter. And since your method is not "serializing" anymore, you should give it a better name.
Applying all that, your code should be:
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
private ArrayList<Student> studentList = new ArrayList<>();
public void writeToFile() {
Path file = Paths.get("EnrolledStudentsSerial.txt");
try (BufferedWriter output = Files.newBufferedWriter(file, CREATE, APPEND, WRITE)) {
output.write("Course: " + this.name + "\n\nEnrolled Students: ");
for (Student student : studentList) {
String content = "\n\tStudent Name: " + student.getName() +
"\n\tStudent Department: " + student.getDepartment() +
"\n\tStudent Age: " + student.getAge() + "\n";
output.write(content);
}
output.write("\n");
} catch (IOException ioe){
System.out.println("Error: " + ioe.getMessage());
}
}

Related

How to sort user input to text files in Java?

I have a program taking user input and setting students in a text file, I want to sort these students in separate text files using the grade average
import java.nio.file.*;
import java.io.*;
import static java.nio.file.StandardOpenOption.*;
import java.util.Scanner;
public class NewClass2
{
public static void main(String[] args)
{
String recOut = "";
String delimiter = ",";
Scanner input = new Scanner(System.in);
final int QUIT = 999;
NewClass1 student = new NewClass1();
try
{
System.out.println("Enter Student ID: ");
student.setStudentId(input.nextInt());
while(student.getStudentId() != QUIT)
{
System.out.println("Enter Student Last Name: ");
student.setLastName(input.next());
System.out.println("Enter Student First Name: ");
student.setFirstName(input.next());
System.out.println("Enter Student Grade Point: ");
student.setGradePoint(input.nextDouble());
if(student.getGradePoint()>=3.6)
{
Path fileOut = Paths.get("HonorsStudentList.txt");
OutputStream output = new BufferedOutputStream(Files.newOutputStream(fileOut, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
recOut = student.getStudentId() + delimiter + student.getLastName() + delimiter + student.getFirstName() + delimiter + student.getGradePoint();
writer.write(recOut, 0,recOut.length());
writer.newLine();
writer.close();
}
if(student.getGradePoint()<3.6 && student.getGradePoint()>=2.0)
{
Path fileOut = Paths.get("GoodStandingStudentList.txt");
OutputStream output = new BufferedOutputStream(Files.newOutputStream(fileOut, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
recOut = student.getStudentId() + delimiter + student.getLastName() + delimiter + student.getFirstName() + delimiter + student.getGradePoint();
writer.write(recOut, 0,recOut.length());
writer.newLine();
writer.close();
}
if(student.getGradePoint()<2.0)
{
Path fileOut = Paths.get("ProbationStudentList.txt");
OutputStream output = new BufferedOutputStream(Files.newOutputStream(fileOut, CREATE));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output));
recOut = student.getStudentId() + delimiter
+ student.getLastName() + delimiter
+ student.getFirstName() + delimiter
+ student.getGradePoint();
writer.write(recOut, 0,recOut.length());
writer.newLine();
writer.close();
}
System.out.println("Enter Student ID: ");
student.setStudentId(input.nextInt());
}
}
catch(Exception e)
{
System.out.println("<<Something bad happened!>>");
System.out.println(e.getMessage());
}
}
}
I've been experimenting with if statements but that's not working because I can't close the writer correctly causing it to only take in one line then stopping.
How do I do this correctly?
The problem is not with how you're closing the file but with how your opening the file. Every time you're opening the file you are creating a new file and writing one line, then closing it, which is overwriting the old file that existed before. What you want to do is create the file if it does not exist, but if it does exist append one line.
Simply change
Files.newOutputStream(fileOut, CREATE)
to
Files.newOutputStream(fileOut, CREATE, APPEND)
Alternatively, you could open/close the files outside the loop or use “try with resources” too.
Since these are only three files, it is probably the easiest to open all three writers at once at the start and keep them open until the end.
If you don't want to close the writers manually (ans at least java 7 or 8 i think), you can use a try-with-resources statement.
Btw you probably don't need to wrap the OutputStream in a BufferedOutputStream, since you already use a buffered writer.
Instead of writing each time in file why don't you try to make three lists(one for every grade range you need) and when you have no more students then write them to separate files.
Something like this:
List<Student> honorsStudent = new ArrayList<Student>();
List<Student> goodStandingStudent = new ArrayList<Student>();
List<Student> probationStudent = new ArrayList<Student>();
// ....
if (student.getGrade() >= 3.6) {
honorsStudent.add(student);
} else if (student.getGrade() >= 2) {
goodStandingStudent.add(student);
}
else {
probationStudent.add(student);
}
//while loop end
//write your files

BufferedWriter write string line by line

Hello I am building a program that writes an output to a text file.
In my program my String looks like this:
MyName
Addres
Location
Paycheck
But when I write it to a text file it looks like this:
MyName Addres Location Paycheck
I am writing everything from a single toString method. How can I use bufferedwriter so that it formats the string while writing it?
Here's my code:
if (file != null) {
FileWriter fileWriter = null;
try {
fileWriter = new FileWriter(file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
BufferedWriter out = new BufferedWriter(fileWriter);
try {
out.write(emp.toString());
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
EDIT:
Here is the toString method for the emp class:
#Override
public String toString() {
return "Name: " + name + " \nDOB: " + dob + " \nAddress: " + address + " \n******Paycheck******\nSalary: "
+ myPaycheck.getSalary() + "\nFederal Income: " + myPaycheck.getTaxes() + "\nSocial Security: "+ myPaycheck.getSocialSecurity() + "\nMedicare: " + myPaycheck.getMedicare()
+ "\nNet Salary: " + myPaycheck.getNetPay() + "";
}
bufferedwriter API
You can use "newLine" easily .
bw.newLine();
You either need to use System.lineSeparator() while writing text to file or change your toString() method to add a line separator between each line or object added
Edit
Your code writes your string as separate line only. Try reading the lines from output file and print each line, you will see that the reader treats each detail as separate line. Now if you wish to write it into the file with exact format so that it is shown in next line in file u have to give the inputs separately maybe by adding the objects to an ArrayList and iterating the same.

Why is this code for making a file from user input using the Scanner class not working?

My code is used to create a file inside a folder of a directory, with the file containing a heading at the top based on what the user inputs.
import java.util.*;
import java.text.*;
import java.io.*;
public class setup {
public static void main(String[] args) {
Scanner userin = new Scanner(System.in);
int hwnum;
String hwsummary;
int period;
String name;
System.out.println("Enter name: ");
name = userin.next();
System.out.println("Enter APCS period: ");
period = userin.nextInt();
System.out.print("Enter HW number: ");
hwnum = userin.nextInt();
System.out.println("Enter HW summary: ");
hwsummary = userin.next();
System.out.println("Enter file name: ");
String hwname = userin.next();
hwname = hwname + ".java";
new File("/hw" + hwnum).mkdirs();
new File("/hw" + hwnum +"/" + hwname);
String filename;
filename = "\\hw" + hwnum + "\\" + hwname;
System.out.println("/*");
System.out.println(name);
System.out.println("APCS1 " + "pd" + period);
System.out.println("HW" + hwnum + " -- " + hwsummary);
System.out.println(getdate());
System.out.println("*/");
}
public static String getdate() {
DateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
String todaydate;
todaydate = dateformat.format(date);
return todaydate;
}
}
The end result of the code, if give by the user should be a java file in a directory named "/hwxx" and should have a heading similar to:
/*
Name
APCS1 pdx
HW# - HWSUMMARY
DATE
*/
System.out.println() can't be used to write to a file, only to print text to the standard output stream. A FileWriter and BufferedWriter can be used instead to write to a file. Try replacing the last part of your main method with this:
try {
FileWriter outputStream = new FileWriter(filename);
try (BufferedWriter out = new BufferedWriter(outputStream)) {
out.write("/*");
out.newLine();
out.write(name);
out.newLine();
out.write("APCS1 pd" + period);
out.newLine();
out.write("HW" + hwnum + " -- " + hwsummary);
out.newLine();
out.write(getdate());
out.newLine();
out.write("*/");
}
} catch (IOException ex) {
// some sort of error message here
// this block will only be run if the program is unable to create or write to the specified file
}
Note that the write() method is the file-writing equivalent to print() rather than println(), so it's necessary to include the newline() method between each line of text to avoid having it all be written to the same line of text. However, a shorter and less tedious alternative is to add the string "\n" (newline) to the end of each line written to the file, like this:
out.write("/*\n");
out.write(name + "\n");
//etc.
If you choose to do it this way and it ends up writing all the text to a single line anyway (a common problem if you're running Windows), use "\r\n" instead of just "\n".

Write string to a specific position in file

I am using BufferedWriter to write strings to a file like this:
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class Test {
public static void main(String[] args) throws IOException {
String myname = "JOHN DOE MAXWELL";
String myotherName = "MELCHIZEDEK NEBUCHARDINEZZAR";
String mylocation = "SOUTH EAST";
String myotherlocation = "SOUTH WEST";
File f = new File("MyFile.txt");
BufferedWriter bw = new BufferedWriter(new FileWriter(f));
bw.write(myname + " " + mylocation);
bw.newLine();
bw.write(myothername + " " + myotherlocation);
bw.close();
}
}
I need to write mylocation such that whatever the length of the string myname, the beginning position of mylocation will not be affected. Please assist.
My Outputshould be:
JOHN DOE MAXWELL SOUTH EAST
MELCHIZEDEK NEBUCHARDI SOUTH WEST
You could do
bw.write(String.format("%-20s%s%n", myName, myLocation));
You can use PrintWriter to use printf() which does both.
e.g. Using PrintWriter
pw.printf("%-" + myNameWidth + "s%s%n", myName, myLocation);
try this
bw.write(myname + " ".substring(0, 30) + " " + mylocation);
Using Google Guava:
Strings.padEnd("JOHN DOE MAXWELL", 26, ' ').length()
String will be always 26 characters length.
such that whatever the length of the string myname, the beginning
position of mylocation will not be affected
The only case i can think of is when each one is in a new line.
You must specify the maximum tolerted length after which this order is no longer guaranteed, the formating actually should occur on reading the file, at that point you can determine the longest variable of myname and format your output according to it.

Get data from rdf file [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
Java - Using Jena APi - Get data from RDF file
I'm using Java and Jena API.
I have the class Person with the datatype properties hasFirstName, hasLastName, hasDateOfBirth, hasGender.
Here is how one person is represented in my RDF file.
<rdf:Description rdf:about="http://www.fam.com/FAM#Bruno04/02/1980 ">
<j.0:FAMhasGender>H</j.0:FAMhasGender>
<j.0:FAMhasDateOfBirth>04/02/1980</j.0:FAMhasDateOfBirth>
<j.0:FAMhasLastName>DS </j.0:FAMhasLastName>
<j.0:FAMhasFirstName> Bruno</j.0:FAMhasFirstName>
</rdf:Description>
I'd like to get for each person the firstname, gender, date of birth and write that information in a text file. The problem I have is that it only writes the first woman/man he finds in the rdf file, but there is more than one woman and man.
Can you please explain me how can I solve this?
Thank you very much.
ExtendedIterator instances = onto.person.listInstances();
Individual instance = null;
Individual firstInstance = null;
while (instances.hasNext()) {
instance = (Individual) instances.next();
gen = instance.getPropertyValue(onto.hasGender).toString();
fname = instance.getPropertyValue(onto.hasFirstName).toString();
dd = instance.getPropertyValue(onto.hasDateOfBirth).toString();
writeFile(fname, dd, genr);}
// Write text file
public void writeFile(String fn, String dbir, String gn) {
String fileout = "D:/file1.txt";
String firstName = fn;
String dateB = dbir;
String gender = gn;
BufferedWriter out;
try {
out = new BufferedWriter(new FileWriter(fileout, true));
if (gender.equals("F")) {
out.write("[label= \"" + firstName + " \"\n\n\"D.Naiss:" + dnai1 + "\", " + shape + "]");
} else if (gender.equals("M")) {
out.write("[label= \"" + firstName + " \"\n\n\"D.Naiss:" + dnai1 + "\", " + shape2 + "]");
}
out.newLine();
// flushes and closes the stream
out.close();
} catch (IOException e) {
System.out.println("There was a problem:" + e);
}
}
Your problem has nothing to do with Jena or RDF but is rather a logic error in your coding.
You call writeFile() inside your while loop which opens a new file, writes the current entry and closes the file. So you are repeatedly overwriting your file with a single entry at one time so you will only ever end up with a single person in the file.
You need to refactor the code to open the file once before the while loop, have the writeFile() method simply add to that file (and not close it) and then close the file after the while loop.
Also as #Udo Kilmaschewski pointed out in your apparent duplicate the genr variable is not defined in the code you showed so you don't appear to be correctly passing the gender from your while loop to the writeFile() function.

Categories