Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm making a typing only game(no graphics) in which I need to save the state of the game and reload later. I've been thinking but could think of nothing(I'm not a very experienced programmer). Could someone enlighten me?
You need your class to implement Serializable interface. Then write the object to a file. Then on start up read the file back again.
To serialize an object means to convert its state to a byte stream so
that the byte stream can be reverted back into a copy of the object. A
Java object is serializable if its class or any of its superclasses
implements either the java.io.Serializable interface or its
subinterface, java.io.Externalizable. Deserialization is the process
of converting the serialized form of an object back into a copy of the
object.
The beauty of Serialzable interface is that you do not need to implement any methods. It is a marking interface. You just make a class Serializable and then write it out to a file.
Word of caution here: You need to truncate the file every time you write to it. Do not try to append data to it. It corrupts the header of the file.
Tutorials here: http://docs.oracle.com/javase/tutorial/jndi/objects/serial.html
You can use ObjectOutputStream and call its method writeObject to save your game state.
And use ObjectInputStream and call its method readObject to load game states.
e.g.
Save Game state
public void saveGameDataToFile(File file) {
try {
FileOutputStream fileStream = new FileOutputStream(file);
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(flag);
objectStream.writeObject(color);
objectStream.writeObject(snake);
objectStream.writeObject(food);
objectStream.writeObject(new Integer(score));
objectStream.writeObject(barrier);
objectStream.writeObject(new Boolean(needToGenerateFood));
objectStream.writeObject(new Boolean(needToGenerateBarrie));
objectStream.close();
fileStream.close();
JOptionPane.showConfirmDialog(frame,
"Save game state successfully.",
"Snake Game",
JOptionPane.DEFAULT_OPTION);
} catch (Exception e) {
JOptionPane.showConfirmDialog(frame,
e.toString() + "\nFail to save game state.",
"Snake Game",
JOptionPane.DEFAULT_OPTION);
}
}
Load Game state
public void loadGameDataFromFile(File file) throws ClassNotFoundException{
... ...
FileInputStream fileStream = new FileInputStream(file);
ObjectInputStream objectStream = new ObjectInputStream(fileStream);
svaedFlag = (int[][]) objectStream.readObject();
savedColor = (Color[][]) objectStream.readObject();
savedSnake = (Snake) objectStream.readObject();
savedFood = (Grid) objectStream.readObject();
savedScore = (Integer) objectStream.readObject();
savedBarriers =(Barriers) objectStream.readObject();
savedNeedToGenerateFood = (Boolean)objectStream.readObject();
savedNeedToGenerateBarrie = (Boolean)objectStream.readObject();
... ...
}
for persisting the Object state you can
use serialization
safe the contents to file as text or xml
save the contents to database (sqlLite,hsql)
Related
I am given an assignment where we are not allowed to use a DB or libraries but only textfile for data storage.
But it has rather complex requirements, for e.g. many validations, because of that, we need to "access the db" (i.e. read the textfile) many times.
My question is: should I create a class like this:
class SomeRepository{
static ArrayList<Users> users = new ArrayList();
public SomeRepository(){
//instantiate this class on program load
//In constructor, we read the text file, instantiate and store everything inside the arraylist.
}
//public getOneUser(){ // for get methods, we don't read from text file at all }
/public save() { //text file saving code overhere }
}
Is this a good approach to solve the above problem? Currently, what we are doing is reading and writing to the text file every time we want to retrieve some data or write something new.
Wouldn't this be too expensive in terms of heap space memory? Or should I just read/write to the text file for every method?
public class IOManager {
public static void writeObjToTxtFile(String fileName, Object object) {
File file = new File(fileName + ".txt");//File will be created in the root directory where the program runs.
try (FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);) {
oos.writeObject(object);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Object readObjFromTxtFile(String fileName) {
Object obj = null;
File file = new File(fileName + ".txt");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
ObjectInputStream ois = new ObjectInputStream(fis);
obj = ois.readObject();
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
return obj;
}
}
Add this class to your project. Since it's general for all Objects, you can pass and receive Objects like these as well: ArrayList<Users>. Play around and Tinker with it to fit whatever your specific purpose is. Hint: You can write other custom methods that calls these methods. eg:
public static void writeUsersToFile(ArrayList<Users> usersArrayList){
writeObjToTxtFile("users",usersArrayList);
}
Ps. Make sure your Objects implement Serializable. Eg:
public class Users implements Serializable {
}
I would suggest reading the contents of your file to a dynamic list such as an arraylist at the start of your program. Make the required queries/changes to your arraylist and then write that arraylist to your file when the program is set to close. This will save significant time over repeated file reads/writes.
This isn't without it's drawbacks, though. You don't want to hogg up memory in case of very large files - but considering this is an assignment, that may not be the case. Additionally, should your program terminate prior to the write at the end, all changes made to your database during the current execution will be lost.
I am writing a small program to help with planning future workouts. I am nearly finished however saving and loading is giving me some trouble. The program works with a list of "ride"(a custom class) objects that hold a number of qualities (like a Dat, and then some ints and doubles)
right now, I have two methods, a "saver" and a "loader":
public void saver() {
try{ // Catch errors in I/O if necessary.
// Open a file to write to, named SavedObj.sav.
FileOutputStream saveFile=new FileOutputStream("SaveObj.sav");
// Create an ObjectOutputStream to put objects into save file.
ObjectOutputStream save = new ObjectOutputStream(saveFile);
// Now we do the save.
for (int x = 0; x < rides.size(); x++) {
save.writeObject(rides.get(x).getDate());
save.writeObject(rides.get(x).getMinutes());
save.writeObject(0);
save.writeObject(rides.get(x).getIF());
save.writeObject(rides.get(x).getTss());
}
// Close the file.
save.close(); // This also closes saveFile.
}
catch(Exception exc){
exc.printStackTrace(); // If there was an error, print the info.
}
}
public void loader() {
try{
// Open file to read from, named SavedObj.sav.
FileInputStream saveFile = new FileInputStream("SaveObj.sav");
// Create an ObjectInputStream to get objects from save file.
ObjectInputStream save = new ObjectInputStream(saveFile);
Ride worker;
while(save.available() > 0) {
worker = new Ride((Date)save.readObject(), (int)save.readObject(), (double)save.readObject(), (double)save.readObject(), (int)save.readObject());
addRide(worker.getDate(), worker.getMinutes(), 0, worker.getIF(), worker.getTss());
}
// Close the file.
save.close(); // This also closes saveFile.
}
catch(Exception exc){
exc.printStackTrace(); // If there was an error, print the info.
}
}
When I run the program, neither "save" nor "load" return any errors. A .sav file is created when one does not exist, and is edited each time the program is executed. Yet, the program never restores data from previous sessions. Please let me know if more information is required.
Thanks in advance for the help!
Don't use available() which returns the number of bytes that can be read without blocking. It doesn't mean what all bytes were read.
If your objects are never null, you could use Object readObject() to check if all data were read from the inputstream.
Date date = null;
while( (date = (Date)save.readObject()) != null) {
worker = new Ride(date, (int)save.readObject(), (double)save.readObject(), (double)save.readObject(), (int)save.readObject());
addRide(worker.getDate(), worker.getMinutes(), 0, worker.getIF(), worker.getTss());
}
Otherwise if read values may be null, you could serialize directly the Ride object or a class containing all fields to serialize rather than unitary fields which could be null With this, the check to know if all data were read with Object readObject() could work.
Do not use available() as a condition. It just tells you whether there is some byte available for immediate reading without any delay, it does not mean the stream has reached its end.
Also you should maybe add a BufferedInputStream and BufferedOutputStream between the Object and File streams, that's almost always a good idea.
To solve your issue you could e. g. first write an integer in the save method that tells you how many objects are in the file and on load read that integer and then make a simple for loop with this amount.
Or you could throw in a PushbackInputStream in the row and then as EOF check use its read() method. It will return -1 on EOF and you can abort reading. If it returns anything else, you unread() the read byte and use the ObjectInputStream that you placed on top.
I am creating a little GUI for a "movie manager" with Java and Swing.
I have a class MovieTableModel that extends AbstractTableModel and has the data for the rows of the table in an Object[][]data.
A second class MovieUI manages the JFrame and well, the GUI in general.
The last class MovieManager is actually just a main function to create an instance of movieui and make it visible.
Now my problem is that by now, data is "saved" in my code. I want it to be able to be loaded and saved. If there is no save-file, one should be created and I should be able to add or delete rows of it (the actionlisteners are already set up, I just need a way to handle the file).
So the GUI looks like this:
MovieManager
This is kinda what I tried:
File tabledata = new File("tabledata.class");
if (!tabledata.exists()) {
try {
tabledata.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
tabledata.
FileInputStream in = new FileInputStream("tabledata.class");
ObjectInputStream input = new ObjectInputStream(in);
Object data = input.readObject();
System.out.print(data);
Both didn't work - I think I do understand how this works in general, but I don't know how to make it to the data in my table, especially as it is saved as an Object[][] but the file is an Object.
And if that works out - how can I add or delete single rows?
Thanks for your help in advance! :)
If you serialize you tablemodel or the object that backs your tablemodel, then you can read it later and restore it to the JTable.
When you read the object again from the ObjectInputStream, I think you are missing the cast to the right type you are saving:
FileInputStream in = new FileInputStream("tabledata.class");
ObjectInputStream input = new ObjectInputStream(in);
Object[][] data = (Object[][])input.readObject();
After you create new file you need to write the data using ObjectOutputStream and then read it with ObjectInputStream.
Object[][] data;
//save
File tabledata = new File("tabledata.dat"); //I wouldn't use class extension (class is for compiled Java)
//creation of file omitted
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(tabledata));
out.writeObject(data);
out.close();
//load
ObjectInputStream in = new ObjectInputStream(new FileInputStream(tabledata));
data = (Object[][]) in.readObject(); //explict cast required
in.close();
Because this stores all data as one big chunk I don't think it is possible to just read/write one element. You would have to resort to counting bytes of stored objects and then skip to right position. If you would really need to store huge amount of table data I would use some relational database as backend. Otherwise I wouldn't bother with such optimization. Just rewrite everything on save.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm creating a sport prediction game for my Grade 11 year and I'm having issues writing data to a text file. I'm using NetBeans 7.3.1. I'm using a button where every time it is pressed data entered by the user must be written to the text file. The text file is empty in the beginning and I need to add data to it. After the first click on the button the data keep rewriting itself and the new data is not added. It needs to be in a new line each time. Thank you very much. Some coding would be awesome!
I just did a quick search for appending to a file (usually a good thing to do): this question seems to be what your looking for.
I haven't tested this, but this should work:
private boolean appendToFile(String fileName, String data, String lineSeparator)
throws IOException {
FileWriter writer = null;
File file = new File(fileName)
if (!file.exists()) {
file.createNewFile();
}
try {
writer = new FileWriter(fileName, true);
writer.append(data);
writer.append(lineSeparator);
} catch (IOException ioe) {
return false;
} finally {
if (writer != null) {
writer.close();
}
}
return true;
}
Desclaimer My question is different from two following links
Question 1
Question 2
public class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
The problem with above solutions is that they do not support writing multiple objects to appendable stream w/o closing the stream.
If I open appendable stream, write multiple objects - then at time of reading I can read only first object properly and on trying to read second object, I get EOF exception.
If I proceed the way like write on object to appendable stream, close stream. Then again open stream, write another object close and so on. This way I am able to read multiple objects properly.
fileOutputStream = new FileOutputStream("abc.dat",true);
outputBuffer = new BufferedOutputStream(fileOutputStream);
objectStream = new AppendableObjectOutputStream(outputBuffer);
BucketUpdate b1 = new BucketUpdate("getAllProducts1",null,"1",null);
BucketUpdate b2 = new BucketUpdate("getAllProducts2",null,"2",null);
BucketUpdate b3 = new BucketUpdate("getAllProducts3",null,"3",null);
objectStream.writeObject(b1);
objectStream.writeObject(b2);
objectStream.writeObject(b3);
objectStream.close();
Calling ObjectOutputStream.reset() after writing each object will fix this.
If you check question you mentioned, you will see that you have to use AppendableObjectOutputStream only to append objects to file, if file already contains some objects. For empty file you have to use ordinary ObjectOutputStream because the header should be written to the beginning in this case.