Why I can't get objects from file properly? - java

I have list of custom objects that I writre and then read to file.
Here is my class:
public class Book implements Serializable{
private int isbn;
private String category;
private String authorName;
public int getIsbn() {
return isbn;
}
public String getCatId() {
return category;
}
public void setIsbn(int isbn) {
this.isbn = isbn;
}
public void setCategory(String category) {
this.category = category;
}
public void setAuthorName(String authorName) {
this.authorName = authorName;
}
public String getAuthorName() {
return authorName;
}
public Book() {}
//copy book
public Book(Book book, int id) {
this.category = book.category;
this.title = book.title;
this.authorName = book.authorName;
this.isbn = id;
}
}
Here is function that I use to write the list of objects:
private static <T> void writeToFile(List<T> items, String fileName) {
try {
String path = "src\\hw1\\library\\repos\\" + fileName;
FileOutputStream f = new FileOutputStream(path, true);// true- means append to file
ObjectOutputStream o = new ObjectOutputStream(f);
// Write objects to file
o.writeObject(items);
o.close();
f.close();
} catch (Exception e) {}
}
And here is function that I reade from the list:
private static <T> List<T> readFromFile(Context context, String fileName) {
try {
String path = "src\\hw1\\library\\repos\\" +fileName ;
FileInputStream fi = new FileInputStream(path);
ObjectInputStream oi = new ObjectInputStream(fi);
// Read objects
List<T> items = (List<T>)oi.readObject();
oi.close();
fi.close();
return items;
} catch (Exception e) {}
return null;
}
The List of objects is written to the file,
but when I try to read it with function above the objects that I get from file only objects that was written to file first time.
Any idea why I get from file only objects that was written to file first time?

I only asume that
but when I try to read it with function above the objects that I get
from file only objects that was written to file first time.
Single write will put given list into a file, second write will put another list into that file - because you are appending to file
Now, you read method always reads from the begining so every invocation of readFromFile will result in reading the same (very first) object (list in your case) from given file. You would have to do do more f.readObject() on the same stream.
If you are not going to read all objects at once, I would suggest to use 1 file per list, so you will not have use file seeking to "shift" position of file pointer (nor doing empty f.readObject() invocations)

Related

I want to read object created in my file using ObjectInputStream ,But it gives exception that java.io.EOFException

I have successfully created an object in a file using ObjectOutputStream but when i try to read that obj it gives an exception.
Please help I am unable to handle this::java.io.EOFException
public class ObjInputObjOutput {
public static void main(String[] args) {
FileInputStream fs;
ObjectInputStream os;
try{
fs=new FileInputStream("C:\\Users\\MYPC\\Desktop\\temp.txt");
os=new ObjectInputStream(fs);
os.readObject();
Student s=(Student) os.readObject();
s.toString();
}catch(Exception e){System.out.println(e);}
}
}
class Student implements Serializable
{
int rno;
String add;
float cgpa;
String name;
public Student(int rno, String add, float cgpa, String name) {
this.rno = rno;
this.add = add;
this.cgpa = cgpa;
this.name = name;
}
public String toString()
{
return "Roll no:"+rno+"\n"+"Add"+add+"\n"+"Cgpa"+cgpa+"\n"+"Name"+name;
}
}
You are reading the object and throwing it away:
os.readObject();
and then trying to read another object that isn't there:
Student s=(Student) os.readObject();
and then converting that to a String and throwing it away:
s.toString();
You only need the second of these three lines.
NB Serialized data is not text, and should not be stored in files with the ".txt" extension. You also should not use full pathnames. Your home directory won't be there on somebody else's computer.

How to write object to and read object from file using servlet

i am trying to write objects of a POJO class to a file and read them with the same Servlet with the Java serialization methods. I have the POJO in a public class and the writer and reader codes in two other public classes. I then accessed both the writer and reader methods in a servlet. The problem is that only the last object written to the file could be deserialized. It seems previously written objects were overwritten. See the codes below please.
The POJO class:
public class Comment implements Serializable{
private String name;//max 24 digits
private String date;//6 digits
private String email;//max 24 digits
private String comment; //to be stored into database as clob no max
private String id;//auto generated
public Comment(){}
public Comment(String id){
this.id = id;
}
public Comment(String name, String email, String comment){
this.name=name;
this.date=date;
this.email=email;
this.comment=comment;
}
public Comment(String name, String date, String email, String comment){
this.name=name;
this.date=date;
this.email=email;
this.comment=comment;
}
public Comment(String name, String date, String email, String comment, String id){
this.name=name;
this.date=date;
this.email=email;
this.comment=comment;
this.id=id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* #return the date
*/
public String getDate() {
return date;
}
/**
* #return the email
*/
public String getEmail() {
return email;
}
/**
* #param email the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* #return the id
*/
public String getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(String id) {
this.id = id;
}
/**
* #return the comment
*/
public String getComment() {
return comment;
}
/**
* #param comment the comment to set
*/
public void setComment(String comment) {
this.comment = comment;
}
Comment myComment;
#Override
public int hashCode()
{
return 31 + id.hashCode();
}
#Override
public boolean equals(Object obj) {
if(obj instanceof Comment){
Comment another = (Comment)obj;
if(this.getId()==another.getId()){
return true;
}
}
return false;
}
public String toString(){
StringBuilder sb = new StringBuilder();
return sb.append(name).append(",").append(" ").append(date).append(",").append(" ").append(comment).append(",").append(" ").append(id).append(",").append(" ").append(email).toString();
}
public void setDate(String date) {
this.date = date;
}
}
The writer class:
public class ObjectStreamWriterExample {
public void write(Object obj){
File outFile = new File("out.txt");
try(ObjectOutputStream objectOutput = new ObjectOutputStream(new FileOutputStream(outFile));){
List <Object> commentList = new ArrayList<>();
commentList.add(obj);
for(Object list : commentList){
objectOutput.writeObject(list);
//System.out.println("good ok now");
}
}catch(IOException io){
System.err.println("An Error occured :");
System.out.println(io.getCause());
}
}
}
Reader class:
public class ObjectStreamReaderExample {
public List <Comment> read( String inFile){
Comment comment = null;
List <Comment> list = new ArrayList<>();
try(ObjectInputStream oi = new ObjectInputStream(new FileInputStream(inFile));){
while(true){
try {
comment = (Comment)oi.readObject();
list.add(comment);
break;
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}catch(EOFException eof){
System.err.println("Reached End of File");
eof.printStackTrace();
}
}
}catch(IOException io){
System.err.println("Error :");
io.printStackTrace();
}
return list;
}
}
The servlet:
public class ObjectStreamExample extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
ObjectStreamWriterExample oswe =new ObjectStreamWriterExample();
oswe.write(new Comment("Omobolaji", "omo#javanice.net", "omo is commenting"));
oswe.write(new Comment("Omobolaji", "omo#javanice.net", "omo is commenting again"));
oswe.write(new Comment("Omobolaji", "omo#javanice.net", "omo is commenting again hhhhh"));
ObjectStreamReaderExample osre = new ObjectStreamReaderExample();
List <Comment> list = new ArrayList<>();
list = osre.read("out.txt");
for(Comment myList : list){
out.println(myList.getName() + "<br> ");
out.println(myList.getEmail() + "<br> ");
out.println(myList.getComment() + "<br> ");
}
}
#Override
public String getServletInfo() {
return "Short description";
}// </editor-fold>
}
No mystery. Every time you call write() you create a new file and write one object to it. You also create a completely pointless list, add the one object to it, iterate the list, once, of course, and write the one object you find in it to the file. Next time you call write(), you do all this nonsense again. Result: one file, with one object in it.
You need to completely reconsider all this. You can't append to object stream files without special measures. You should:
Create the file by opening it for output.
Write as many objects to it as you wish.
Close the file.
Open the file for input.
Read objects from it until you reach end of file, which is signalled by, err, an EOFException.
Close the input file.
OR
Create a list.
Append as many objects as you wish to the list.
Open the file for output, serialize the list, close the file.
Open the file for input, deserialize one object, the list, and iterate it to recover all the original objects, and close the input file.
NB
Object streams are not text, and should not be saved in files with the .txt extension.
The fact that you're in a servlet is irrelevant.

How to Insert ArrayList data to the DataBase

Im try to insert data into Database using ArrayList.there is a Erro msg.
That is my Custmer.class method. this is what i got from when i going to pass ArrayList into another class.
incompatible types: ArrayList<String> cannot be converted to ArrayList<Inquiries>
I want to know how to do this using correct Using OOP concept
public void passingMsg(ArrayList<Inquiries> arrlist){
try {
System.out.println("Method "+arrlist);
String sq = "INSERT INTO Inquiries (name,mail,tp,msg)VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for(int i=0;i<arrlist.size();i++){
pr.setString(1,arrlist.get(i).getName());
pr.setString(2,arrlist.get(i).getMail());
pr.setString(3,arrlist.get(i).getTp());
pr.setString(4,arrlist.get(i).getMsg());
}
pr.executeQuery();//executeBatch();
} catch (SQLException ex) {
}
}
and this is how i get values from user
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
Custmer c =new Custmer();
if( c.passingMsg(arrInq)){
try {
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
}
and this is my Inquiries.class :
public class Inquiries {
private String name;
private String mail;
private String tp;
private String msg;
public Inquiries(String name,String mail,String tp,String msg){
this.name = name;
this.mail = mail;
this.tp = tp;
this.msg = msg;
}
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getTp() {
return tp;
}
public void setTp(String tp) {
this.tp = tp;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Can Some one please explain whats wrong with this. please ?
Reason For Error
This was simply telling you that your types were incompatible for the operation you were trying to perform. In your passingMsg() method, you have its header as: public void passingMsg(ArrayList<Inquiries> arrlist). However, inside your "how i get values from user" area, which I will now refer to as "2nd Snippet", you have your method call declared as: if( c.passingMsg(arrInq)). This means that you are implying that your parameter being passed, arrInq in this case, is of the type ArrayList<Inquiries>, but it's not. It's being initialized in your 2nd Snippet as: ArrayList<String> arrInq = new ArrayList<String>();
Simple Fix
I take no responsibility for this code; use at your own risk. To fix this, you would want to change that entire 2nd Snippet to something similar to the following:
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
Custmer c = new Custmer();
try {
c.passingMsg(arrInq);
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
You would also want to change the method header to either return a boolean, or fix it up a little bit to actually throw the exception. Such as:
public void passingMsg(ArrayList<Inquiries> arrlist) {
System.out.println("Method " + arrlist);
String sq = "INSERT INTO Inquiries(name,mail,tp,msg) VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for (Inquiries inquiries : arrlist) {
pr.setString(1, inquiries.getName());
pr.setString(2, inquiries.getMail());
pr.setString(3, inquiries.getTp());
pr.setString(4, inquiries.getMsg());
}
pr.executeQuery();//executeBatch();
}
Let's talk in O-O-P way.
Here Inquiries is your model, model is nothing but simple class that has instance members and public methods to get and set value of model's instance variable.
Generally we put all database related operations code in their respective models.
e.g. I have model "Model" which typically maps to database table say it as "TableModel" ,I would do something like this:
public class Model{
private int id;
private String attr;
//other properties of the model
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
//other getters and setters
//here we write methods to performs database operations
public void save(){
//use "this" to get properties of object
//logic to save to this object in database table TableModel as record
}
public void delete(int id){
//logic to delete this object i.e. from database table TableModel
}
public Model get(int id){
//retrieve record from table TableModel with this id
}
//other methods to get data from database.
}
Now question is how I can use this in some another class. Let's say I have list of Model objects and I wish to insert them in to database.I will do it something like this:
public class AnotherClass{
public void someMethod(){
//create list of models objects e.g. get them from user interface
ArrayList<Model> models=new ArrayList<>();
for(int i=0;i<3;i++){
Model model=new Model();
model.setId(i);
model.setAttr("attr"+i);
models.add(model);
}
SomeOtherClass obj=new SomeOtherClass();
obj.insert(models);
}
}
public class SomeOtherClass{
//other code above.....
//my method that inserts each Model object in database
//Note: this is sample method , you should do it in optimized way
// e.g. batch insert
public void insert(ArrayList<Model> models){
for(Model myModel:models){
myModel.save();
}
}
//other code below.....
}
You are using the wrong type parameter for the ArrayList. Instead of ArrayList<String> you need ArrayList<Inquiries>. To fix the problem, you should remove this code ...
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
... and replace it with this code:
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));

Java - Using an object inside an object

I am working on a project ( I had a problem yesterday and so many people helped me!) so I decided to ask for help again.
My code has 3 classes. ProjectMain,Students,Classroom. I created an array of Classroom objects. Right now I have 3 Classroom objects. But I have to assign student objects to these Classroom objects. For example : classarray[0] is an object from Classroom class and studentobject.get(0) , studentobject.get(1) ... will be students objects inside classarray[0] object. But I have failed on this while coding. Here are my classes :
public class Classroom
{
private String classname;
private String word[] = null;
protected ArrayList<Students> studentobject = new ArrayList<Students>(10);
public String[] getWord()
{
return word;
}
public void setWord(String[] word)
{
this.word = word;
}
public ArrayList<Students> getStudentobject()
{
return studentobject;
}
public void setStudentobject(ArrayList<Students> studentobject)
{
this.studentobject = studentobject;
}
public String getClassname()
{
return classname;
}
public void setClassname(String classname)
{
this.classname = classname;
}
public void classroomreader(String filename)
{
// This method gets the name of Classroom
File text = new File("C:/Users/Lab/Desktop/classlists/" + filename
+ ".txt");
Scanner scan;
try
{
scan = new Scanner(text);
String line = scan.nextLine();
word = line.split("\t");
line = scan.nextLine();
word = line.split("\t");
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
}
}
This is my student class :
public class Students extends Classroom
{
private String name,id;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
And my main class :
public class ProjectMain
{
public static void main(String[] args)
{
Classroom[] classarray = new Classroom[3];
//I got 3 Classroom objects here
classarray[0]=new Classroom();
classarray[1]=new Classroom();
classarray[2]=new Classroom();
classarray[0].classroomreader("class1");
classarray[0].studentobject.get(0).setName(classarray[0].getWord()[1]);
//The problem is in here. When my code comes to the line above,
// at java.util.ArrayList.rangeCheck(Unknown Source) error comes out.
// I tried to get first object in studentobject Arraylist, and tried to set it's name
// to the variable which my text reader reads.
How can I write what I have in my mind?
Your classroomreader method reads the file but don't do much of it... maybe you want to create some instance of Students within it.
scan = new Scanner(text);
String line = scan.nextLine();
word = line.split("\t"); // won't be used
line = scan.nextLine();
word = line.split("\t"); // erased here
There you only have the last line (split) of the file in word attribute.
When creating Classroom instance studentobject list is created empty and it stays that way so you can't access first (or any) object in it.
To populate your list you may add to Classroom method like this:
public void addStudent(Student s)
{
studentobject.add(s);
}
classroom contains the following field declaration
String word[] = null;
the main class, incl the classroomreader does not set a value to this field. Yet you are going to invoke
classarray[0].getWord()[1]
which then must fail.
tip: don't use expressions like this, which can be found in your main class (at least not in early stages of development, or learning)
classarray[0].studentobject.get(0).setName(classarray[0].getWord()[1]);
resolve into variables and several steps. Compilers are smart enough to produce the same code if the context is not disturbed, ie the long expression is resolved into a single block.
Never forget that the purpose of programming languages is to make programs readable for humans. :) Code with abbreviations or "tricks" simply shows some philodoxical attitude (imho)

Java Swing Object[][] getData() confusion

Hi I'm having some trouble getting started with a problem in a Java course learning Swing and starting on JTables and getting data into them. It's going to be hard to explain so I'm just going to post the code I was given, along with the question.
The question is:
The getData() method needs to return an Object[][] containing the data represented by the class.
The first class is MusicAlbum
class MusicAlbum {
private String id;
private String name;
private String genre;
private boolean isCompilation;
private int track_count;
public MusicAlbum(String id, String name, String genre, boolean isCompilation, int track_count) {
this.id = id;
this.name = name;
this.genre = genre;
this.isCompilation = isCompilation;
this.track_count = track_count;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getGenre() {
return genre;
}
public boolean isCompilation() {
return isCompilation;
}
public int getTrackCount() {
return track_count;
}
public boolean equals(Object obj) {
if (obj instanceof MusicAlbum)
return this.id.equalsIgnoreCase(((MusicAlbum)obj).id);
return super.equals(obj);
}
}
The class I have to implement the methods in is MusicDataObject (at the bottom)
import java.util.Random;
import java.util.Scanner;
public class MusicDataObject {
private List<MusicAlbum> albums = new ArrayList<>();
private Random random = new Random(); // for generating IDs
public void addAlbum(MusicAlbum album) throws IllegalArgumentException {
if (searchAlbum(album.getId()) != null)
throw new IllegalArgumentException("Album ID is not new!");
albums.add(album);
}
public MusicAlbum searchAlbum(String id) {
for (MusicAlbum album : albums) {
if (album.getId().equalsIgnoreCase(id)) {
return album;
}
}
return null;
}
public MusicAlbum removeAlbum(String id) {
MusicAlbum album = searchAlbum(id);
albums.remove(album);
return album;
}
public void updateAlbum(MusicAlbum album)
throws IllegalArgumentException {
if (removeAlbum(album.getId()) == null)
throw new IllegalArgumentException("Album ID does not exist!");
addAlbum(album);
}
public String generateID() {
String formatter = "A%0" + (int)Math.ceil(Math.log10(albums.size() * 2) + 1) + "d";
String ID;
do {
ID = String.format(formatter, random.nextInt(albums.size() * 2 + 1));
} while (searchAlbum(ID) != null);
return ID;
}
public void saveData(String fileName) throws IOException {
// make sure that the file exists or try to create it
File fout = new File(fileName);
if (!fout.exists() && !fout.createNewFile())
return;
PrintWriter out = new PrintWriter(fout);
for (MusicAlbum album: albums) {
out.println(serializeAlbum(album));
}
out.close();
}
public String serializeAlbum(MusicAlbum album) {
return String.format(
"%s;%s;%s;%b;%d",
album.getId(),
album.getName(),
album.getGenre(),
album.isCompilation(),
album.getTrackCount());
}
public void loadFile(String fileName) throws FileNotFoundException {
albums = new ArrayList<>();
Scanner in = new Scanner(new File(fileName));
while (in.hasNext()) {
// --- split the next line with the character ";"
String line = in.nextLine();
String[] tokens = line.split(";");
// --- construct a new MusicAlbum using the resulting tokens. NOTE: This isn't very robust.
// If a line doesn't contain enough data or the data is invalid, this will crash
albums.add(new MusicAlbum(
tokens[0],
tokens[1],
tokens[2],
Boolean.parseBoolean(tokens[3]),
Integer.parseInt(tokens[4])
));
}
}
// ----- these methods need to be implemented
public Object[][] getData() {
// TODO
}
public String[] getColumnNames() {
// TODO
}
}
The sample data being used is in a txt file, formatted as so:
A01;Defiance;Soundtrack;true;24
A02;Insomniac;Punk Rock;false;14
A03;A Great Day For The Race;Gypsy Jazz;false;10
A04;Viva La Internet;Ska;false;31
A05;New Surrender;Rock;false;17
So basically it's this getData() method they want me to implement that is giving me grief. I don't fully understand what they want me to do, nor do I fully understand what the Object[][] does.
I hope I have been clear enough, and I will appreciate all help given. Also please try to explain things as best you can and dumb them down as much as possible, I'm new to a lot of this :)
Thanks for your time.
Object[][] is a 2-dimensional array. Each of its element is an Object[], a one-dimensional array.
Your task is to create a 2 dimensional array, having one element (Object[]) for each of your MusicAlbum. An Object[] should hold the properties of a MusicAlbum like id, name, genre, isCompilation and track_count.
You can create an object array like this:
Object[] arr = new Object[] { "some", "values", 23, true };
You can create a 2 dimensional array like this:
Object[][] arr2d = new Object[size][];
And you can iterate over all your MusicAlbums, create an Object[] for each of them containing the properties of that music album, and set it in the arr2d.
You can set/get elements of a 2-dimensional array just like any other arrays:
// Set first element:
arr2d[0] = arr;
// Get first element:
Object[] firstElement = arr2d[0];
The getColumnNames() method should just return a String[] (a String array) containing the column names, the names of the properties.
And it might be obvious but note that the order you return the column names and the order of the property values (in the elements of the Object[]) should be the same.

Categories

Resources