Can't save and load an object to file - java

I guess I don't even have to mention that I am a beginner with Java, and that this is part of an assignment. It has to be pretty obvious. What I want is to count occupied rooms in an apartment booking system, but I am totally stuck. I really can't figure out how to save the value of aptA, aptB and aptM. I need them to load every time I restart the program. Right now I'm getting the following error:
Exception in thread "main" java.lang.RuntimeException: Uncompilable
source code - Erroneous sym type: ObjectInputStream at
apartments1.Person.loadObject(Person.java:348) at
apartments1.Booking.main(Booking.java:24) Java Result: 1
I have a feeling my approach to this might be way wrong though, but this is were I ended up after desperately testing several other solutions... Now it's all a big mess, and I'm about to give up.
//creating the object
public static void addRoomCounter(){
Person roomCounter = new Person();
roomCounter.addAptA();
roomCounter.addAptB();
roomCounter.addAptM();
//adding it to arraylist
ArrayList<Person> roomList = new ArrayList<Person>();
roomList.add(roomCounter);
//saving it to file
try{
FileOutputStream saveFile = new FileOutputStream("Roomcounter.txt");
ObjectOutputStream save = ObjectOutputStream(saveFile); //cannot find symbol
save.writeObject(roomCounter);
save.close();
}catch(Exception exc){
}
}
public int addAptA(){
return aptA;
}
public int addAptB(){
return aptB;
}
public int addAptM(){
return aptM;
}
//loading object
public static void loadObject(){
try{
FileInputStream saveFile = new FileInputStream("Roomcounter.txt");
ObjectInputStream restore = ObjectInputStream(saveFile); //cannot find symbol
Object roomCounter = restore.readObject();
int aptA = (int) restore.readObject();
int aptB = (int) restore.readObject();
int aptM = (int) restore.readObject();
restore.close();
}catch(IOException | ClassNotFoundException exc){
}
}

The issue is with your reading block. You are reading the object but type-casting it to int where it should be Person. i.e.
public static void loadObject(){
try{
FileInputStream saveFile = new FileInputStream("Roomcounter.txt");
ObjectInputStream restore = ObjectInputStream(saveFile); //cannot find symbol
Person roomCounter = (Person) restore.readObject();
int aptA = (int) restore.getAptA();
int aptB = (int) restore.getAptB();
int aptM = (int) restore.getAptC()();
restore.close();
}catch(IOException | ClassNotFoundException exc){
exc.printStackTrace();
}
}
In your example, you were reading the object thrice from the serialized object on file. Rather you need to read it once and then work around.

Related

How to read all objects from ObjectInputStream

I have a file with some info how can I read all info?
Name names;
try (FileInputStream fileInputStream = new FileInputStream(file)) {
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
names = (Name) objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
You have several solution, all depending on the input:
You can iterate until the stream is fully consumed: I think that is the worse solution out of those I provide you. It is worse because you are checking if EOF was reached, whilst you should know when you're done (eg: your file format is wrong).
Set<Name> result = new HashSet<>();
try {
for (;;) {
result.add((Name)objectInputStream.readObject());
}
} catch (EOFException e) {
// End of stream
}
return result;
When producing the input, serialize a collection and invoke readObject() on it. Serialization should be able to read the collection, as long as each object implements Serializable.
static void write(Path path, Set<Name> names) throws IOException {
try (OutputStream os = Files.newOutputStream(path);
ObjectOutputStream oos = new ObjectOutputStream(os)) {
oos.writeObject(names);
}
}
static Set<Name> read(Path path) throws IOException {
try (InputStream is = Files.newInputStream(path);
ObjectInputStream ois = new ObjectInputStream(is)) {
// WARN Files.newInputStream is not buffered; ObjectInputStream might
// be buffered (I don't remember).
return (Set<Name>) ois.readObject();
}
}
When producing the input, you can add a int indicating the number of object to read, and iterate over it: this is useful in case where you don't really care of the collection (HashSet). The resulting file will be smaller (because you won't have the HashSet metadata).
int result = objectInputStream.readInt();
Name[] names = new Name[result]; // do some check on result!
for (int i = 0; i < result; ++i) {
names[i] = (Name) objectInputStream.readObject();
}
Also, Set are good, but since they remove duplicate using hashCode()/equals() you may get less object if your definition of equals/hashCode changed after the fact (example: your Name was case sensitive and now it is not, eg: new Name("AA").equals(new Name("aa"))).

Writing and Reading an ArrayList<model>

So I am pretty much new at this but I have built a library project that has an ArrayList BookList which in return has elements such as String Title, String Author, and int Quantity. I have an add method and a display method and I want to create a method that I am able to save and load the BookList when I I give the appropriate input to do so. Moreover I want to do so, so when I load the BookList I can make changes to the elements in the ArrayList and it's not just reading from the file.
public class Library implements Serializable{...}
Inside this class are my methods of saving and loading which are called in the main as well as the constructors for the ArrayList.
Save
public void save(){
try{
FileOutputStream fileOut = new FileOutputStream("BookList.tmp");
ObjectOutputStream objOut = new ObjectOutputStream(fileOut);
objOut.writeObject(BookList);
objOut.close();
}catch(Exception ev){}
}//end of save()
Load
public void load(){
try{
FileInputStream fileInput = new FileInputStream("BookList.tmp");
ObjectInputStream objInput = new ObjectInputStream(fileInput);
List<Book> BookList = (List<Book>) objInput.readObject();
objInput.close();
}
catch (Exception ev){}
}//end of load()
Display
public void displayBooks(){
String t;
String a;
int q;
String s;
Book bo = new Book();
for(int i = 0; i<BookList.size(); i++){
bo = BookList.get(i);
t = bo.gettitle();
a = bo.getauthor();
q = bo.getquantity();
System.out.println(i + "." + t + " " + a + " " + q);
}//end of loop
}//end of displayBooks()
But so far through the display method I have I am not able to see the BookList so I don't know if the save method works in the first place as well. So I want to know if the problem lies here or somewhere else.
The problem is in your load(), you read the book list from the ObjectInputStream, but you simply assigned to a local variable. I believe (though poorly named) your BookList is an instance variable.
So your load() should look like
public void load(){
try{
ObjectInputStream objInput = new ObjectInputStream(FileInputStream("BookList.tmp"));
this.books = (List<Book>) objInput.readObject();
objInput.close();
}
catch (Exception ignored){
// please add some handling please!
}
}
Most probable cause of your problem is that BookList in display() method and the one in load() method are different.
In display method, you are referring to BookList that is an instance variable but in load method, you have stored the result of objInput.readObject() method in a local variable with the same name BookList. I think you wanted to store the result in BookList that is an instance variable.
Try changing
List<Book> BookList = (List<Book>) objInput.readObject();
to
BookList = (List<Book>) objInput.readObject();

how to set and take in a integer to/from a file in java

So this is a very simple question. I have been trying to research it, and yes I have slightly found some answers but i can't find out how it works so i have come to this.
I am making a simple game in java (pong) and their is a high score integer that i would like to be able save and load from a file (I have heard a lot about using a txt file so probably that, but i have also heard about using a xml i believe is what it is, but i did not look into that as much). How exactly do i program this?
Thank you to all who answer.
PS
I have looked into this code but I don't understand how it's workings
String strFilePath = "C://FileIO//WriteInt.txt";
try {
//create FileOutputStream object
FileOutputStream fos = new FileOutputStream(strFilePath);
DataOutputStream dos = new DataOutputStream(fos);
int i = 100;
dos.writeInt(i);
dos.close();
} catch (IOException e) {
System.out.println("IOException : " + e);
}
The most simplest way is to create a file, i.e.
write the score to a file, e.g.
String user = "John";
int score = 100;
f = new BufferedWriter(new FileReader(filepath));
f.write(user + "=" + score); // assuming "=" is not inside the user name
f.close();
then read from the file when you need it, e.g.
f = new BufferedReader(new FileReader(filepath));
String line = f.readLine().trim();
String[] temp = line.split("="); // now temp is of the form ["John", "100"]
String user = temp[0];
int score = Integer.parseInt(temp[1]);
f.close();
I think you can solve this encoding the object into a file,but it wont be an xml, it will be a custom file that only your app will be able to open
public void save(Integer ... integersToEncode){
try{
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream (new File(/*yourFileName*/)));
for(Integer encoding : integersToEncode)
output.writeObject(encoding);
output.close();
}
catch(Exception e){
//What do you want to do if the program could not write the file
}
}
For reading
public Integer[] read(int size){
Integer[] objects = new Integer[size];
try{
ObjectInputStream input = new ObjectInputStream(new FileInputStream (new File(/*yourFileName*/)));
for(int i = 0; i < size ; i++)
objects[i] = (Integer)input.readObject();
input.close();
}
catch(Exception e){
//What do you want to do if the program could not write the file
}
return objects;
}
Maybe you were confused by the way the original code you posted was printing the char 'd' to the output file. This is the character's ASCII value, as you may know. The following modifications to your code make it work the way you were orginally looking at:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
public class Game {
public static void main(String[] args) throws IOException {
Game game = new Game();
game.writeHighScore();
}
public void writeHighScore() throws IOException{
String strFilePath = "C:/Users/User/workspace/HighScore.txt";
FileInputStream is = null;
DataInputStream dis = null;
FileOutputStream fos = null;
DataOutputStream dos = null;
try
{
//create FileOutputStream object
fos = new FileOutputStream(strFilePath);
dos = new DataOutputStream(fos);
int i = 100;
dos.writeInt(i);
System.out.println("New High Score saved");
dos.close();
// create file input stream
is = new FileInputStream(strFilePath);
// create new data input stream
dis = new DataInputStream(is);
// available stream to be read
while(dis.available()>0)
{
// read four bytes from data input, return int
int k = dis.readInt();
// print int
System.out.print(k+" ");
}
}catch(Exception e){
// if any error occurs
e.printStackTrace();
}finally{
// releases all system resources from the streams
if(is!=null)
is.close();
if(dis!=null)
dis.close();
if(fos!=null)
fos.close();
if(dos!=null)
dos.close();
}
}
}

How to write an int value to a file?

i am trying to implement file handling into a small project i am currently working on. At the moment i can read in and write out an array of objects to an external .txt document but i am also trying to write out an int value which keeps track of the unique id of the last added element to an array List.
I am new to java, especially file handling. I am not sure if i can send in the int value along with the array list or if i need to create a new method and .txt document and write it to that. Below is what i have done so far, as you can see i have tried to send in the int with the array but this is as far as i can get.
public void writeToFile(List<? extends Serializable> team, int maleLastId) {
try {
outByteStream = new FileOutputStream(aFile);
OOStream = new ObjectOutputStream(outByteStream);
OOStream.writeObject(team);
outByteStream.close();
OOStream.close();
} catch(IOException e) {
JOptionPane.showMessageDialog(null,"I/O Error" + e + "\nPlease Contact your Administrator :-)");
}
}
A simple way to write to file is using the BufferedWriter class:
int x = 10;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter("utfil.txt", true));
} catch (IOException e) {
e.printStackTrace();
}
writer.write(x);

SMO,Sequential Minimal Optimization in WEKA

I'm new with Weka. I want to use Sequential Minimal Optimization in WEKA.
Could anyone tell me how to proceed?
here is my Java code but it doesn't work:
public class SVMTest {
public void test(File input) throws Exception{
File tmp = new File("tmp-file-duplicate-pairs.arff");
String path = input.getParent();
//tmp.deleteOnExit();
////removeFeatures(input,tmp,useType,useNames, useActivities, useOccupation,useFriends,useMailAndSite,useLocations);
Instances data = new weka.core.converters.ConverterUtils.DataSource(tmp.getAbsolutePath()).getDataSet();
data.setClassIndex(data.numAttributes() - 1);
Classifier c = null;
String ctype = null;
boolean newmodel = false;
ctype ="SMO";
c = new SMO();
String[] options = {"-M"};
c.setOptions(options);
c.buildClassifier(data);
newmodel = true;
//c = loadClassifier(input.getParentFile().getParentFile(),ctype);
if(newmodel)
saveModel(c,ctype, input.getParentFile().getParentFile());
Evaluation eval = new Evaluation(data);
eval.crossValidateModel(c, data, 10, new Random(1));
System.out.println(c);
System.out.println(eval.toSummaryString());
System.out.println(eval.toClassDetailsString());
System.out.println(eval.toMatrixString());
tmp.delete();
}
private static void saveModel(Classifier c, String name, File path) throws Exception {
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(
new FileOutputStream(path.getAbsolutePath()+"/"+name+".model"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
oos.writeObject(c);
oos.flush();
oos.close();
}
}
I want to know how to provide .arff file?
my Dataset is in the form of XML files.
I guess you have figured it out by now, but in case it helps others, there is a wiki page about it:
http://weka.wikispaces.com/Text+categorization+with+WEKA
to use SMO, let's say you have some train instances "trainset", and a test set "testset"
to build the classifier:
// train SMO and output model
SMO classifier = new SMO();
classifier.buildClassifier(trainset);
to evaluate it using cross validation for example:
Evaluation eval = new Evaluation(testset);
Random rand = new Random(1); // using seed = 1
int folds = 10;
eval.crossValidateModel(classifier, testset, folds, rand);
then eval holds all the stats, etc.
You can Read input file from these line:
Instances training_data = new Instances(new BufferedReader(
new FileReader("tmp-file-duplicate-pairs.arff")));
training_data.setClassIndex(training_data.numAttributes() - 1);
The following link explains about using SMO in weka
http://preciselyconcise.com/apis_and_installations/training_a_weka_classifier_in_java.php

Categories