I made a class that saves and loads objects for my Othello game project. My question is how do I take this saved object and display the saved game board state within it? Thanks in advance for the answers by the way!
public class SaveGame {
public static final String filename = "gameSave.bin";
public void saveGameFile(Serializable object){
FileOutputStream fs = null;
try{
fs = new FileOutputStream(filename);
ObjectOutputStream os = new ObjectOutputStream(fs);
os.writeObject(object);
os.flush();
os.close();
}catch(IOException e){
e.printStackTrace();
}
}
public void load(){
if(checkFileExists()){
FileInputStream fis = null;
try{
fis = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
CreateBoard cb = (CreateBoard) ois.readObject();
ois.close();
System.out.println(cb.toString());
}catch(ClassNotFoundException | IOException e){
e.printStackTrace();
}
}
}
public boolean checkFileExists(){
return new File(filename).isFile(); //Searches directory to make sure file exists
}
Related
I want to write 3 object arrays to the same text file and load the data back to the arrays as well. However, I can only seem to get this to work with arr1 with the below code. How can I change this code to write the data of all 3 arrays to the same file and load the data back to their respective arrays?
import java.io.*;
public class CarCenter implements Serializable {
static CarCenter[] arr1 = new CarCenter[6];
static CarCenter[] arr2 = new CarCenter[6];
static CarCenter[] arr3 = new CarCenter[6];
public static void write() {
try {
FileOutputStream fos = new FileOutputStream("Data.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arr1);
oos.writeObject(arr2);
oos.writeObject(arr3);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void load() {
try {
FileInputStream fis = new FileInputStream("Data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
CarCenter[] saved = (CarCenter[]) ois.readObject();
arr1 = saved;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
In your code you are only loading the value of arr1:
public static void load() {
try {
FileInputStream fis = new FileInputStream("Data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
CarCenter[] saved = (CarCenter[]) ois.readObject();
arr1 = saved;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
All you have to do is to read the other objects as well like this:
public static void load() {
try {
FileInputStream fis = new FileInputStream("Data.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
CarCenter[] saved = (CarCenter[]) ois.readObject();
arr1 = saved;
CarCenter[] saved2 = (CarCenter[]) ois.readObject();
arr2 = saved2;
CarCenter[] saved3 = (CarCenter[]) ois.readObject();
arr3 = saved3;
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
Want to learn more?
I suggest reading the documentation itself.
I'm using DeflaterOutputStream in combination with Buffered input and output streams, trying to just compress a simple file which I should be able to decompress with the second program (it also adds a number at the end of a line but this is irrelevant). However, it's not creating a valid compressed file. When I try to decompress it, it just creates a blank file. I think it might have something to do with flushing. Any thoughts?
public class Program {
static String inputFileName = "inputfile.txt";
static String outputFileName = "outputfile.txt";
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream(inputFileName);
BufferedInputStream inputBuff = new BufferedInputStream(fileInputStream);
FileOutputStream fileOutputStream = new FileOutputStream(outputFileName);
BufferedOutputStream outputBuff = new BufferedOutputStream(fileOutputStream);
DeflaterOutputStream deflater = new DeflaterOutputStream(outputBuff);
int fileByte;
while ((fileByte =inputBuff.read()) != -1)
{
deflater.write(fileByte);
}
deflater.flush();
outputBuff.flush();
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class Program2 {
static String inputFileName = "outputfile.txt";
static String outputFileName = "decoutputfile.txt";
public static void main(String[] args) {
try {
FileInputStream fileInputStream = new FileInputStream(inputFileName);
BufferedInputStream inputBuff = new BufferedInputStream(fileInputStream);
FileOutputStream fileOutputStream = new FileOutputStream(outputFileName);
BufferedOutputStream outputBuff = new BufferedOutputStream(fileOutputStream);
InflaterOutputStream inflater = new InflaterOutputStream(outputBuff);
int fileByte;
int lineCount = 1;
while ((fileByte =inputBuff.read()) != -1)
{
if (fileByte == '\n'){
inflater.write(lineCount);
lineCount++;
}
inflater.write(fileByte);
}
inflater.flush();
outputBuff.flush();
fileOutputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I'm having trouble loading my save file and its showing me a "cannot find symbol" error in the .readObject() of the 2 int variables. I properly declared the variables and both variables are global. I have no idea why. I tried searching for an answer so i end up here. ty in advance guys
public void loadGame()
{
//Load Game
try
{
FileOutputStream saveFile = new FileOutputStream("save.txt");
ObjectOutputStream load = new ObjectOutputStream(saveFile);
cursortrigger = (Integer) load.readObject();
soundtrigger = (Integer) load.readObject();
load.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
public void saveGame()
{
//Save Game
try
{
FileOutputStream saveFile = new FileOutputStream("save.txt");
ObjectOutputStream save = new ObjectOutputStream(saveFile);
save.writeObject(cursortrigger);
save.writeObject(soundtrigger);
save.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
FileOutputStream saveFile = new FileOutputStream("save.txt");
ObjectOutputStream load = new ObjectOutputStream(saveFile);
This is wrong. To read objects, you need ObjectInputStream and FileInputStream.
FileInputStream saveFile = new FileInputStream("save.txt");
ObjectInputStream load = new ObjectInputStream(saveFile);
You need ObjectInputStream, not ObjectOutputStream. Also FileInputStream.
I am going to write multiple objects to a file and then retrieve them in another part of my code. My code has no error, but it is not working properly. Could you please help me find what is wrong about my code.
I read different codes from different websites, but none of them worked for me!
Here is my code to write my objects to a file:
MyClassList is an arraylist which includes objects of my class (which must be written to a file).
for (int cnt = 0; cnt < MyClassList.size(); cnt++) {
FileOutputStream fout = new FileOutputStream("G:\\address.ser", true);
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(MyClassList.get(cnt));
}
I added "true" to the constructor of the outputstream, because I want to add each object to end of the file. Is that correct?
And here is my code to read the objects from the file:
try {
streamIn = new FileInputStream("G:\\address.ser");
ObjectInputStream objectinputstream = new ObjectInputStream(streamIn);
MyClass readCase = (MyClass) objectinputstream.readObject();
recordList.add(readCase);
System.out.println(recordList.get(i));
} catch (Exception e) {
e.printStackTrace();
}
It finally prints out just one object. Now, I don't know if I am not writing correctly or reading correctly!
Why not serialize the whole list at once?
FileOutputStream fout = new FileOutputStream("G:\\address.ser");
ObjectOutputStream oos = new ObjectOutputStream(fout);
oos.writeObject(MyClassList);
Assuming, of course, that MyClassList is an ArrayList or LinkedList, or another Serializable collection.
In the case of reading it back, in your code you ready only one item, there is no loop to gather all the item written.
As others suggested, you can serialize and deserialize the whole list at once, which is simpler and seems to comply perfectly with what you intend to do.
In that case the serialization code becomes
ObjectOutputStream oos = null;
FileOutputStream fout = null;
try{
fout = new FileOutputStream("G:\\address.ser", true);
oos = new ObjectOutputStream(fout);
oos.writeObject(myClassList);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if(oos != null){
oos.close();
}
}
And deserialization becomes (assuming that myClassList is a list and hoping you will use generics):
ObjectInputStream objectinputstream = null;
try {
FileInputStream streamIn = new FileInputStream("G:\\address.ser");
objectinputstream = new ObjectInputStream(streamIn);
List<MyClass> readCase = (List<MyClass>) objectinputstream.readObject();
recordList.add(readCase);
System.out.println(recordList.get(i));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(objectinputstream != null){
objectinputstream .close();
}
}
You can also deserialize several objects from a file, as you intended to:
ObjectInputStream objectinputstream = null;
try {
streamIn = new FileInputStream("G:\\address.ser");
objectinputstream = new ObjectInputStream(streamIn);
MyClass readCase = null;
do {
readCase = (MyClass) objectinputstream.readObject();
if(readCase != null){
recordList.add(readCase);
}
} while (readCase != null)
System.out.println(recordList.get(i));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(objectinputstream != null){
objectinputstream .close();
}
}
Please do not forget to close stream objects in a finally clause (note: it can throw exception).
EDIT
As suggested in the comments, it should be preferable to use try with resources and the code should get quite simpler.
Here is the list serialization :
try(
FileOutputStream fout = new FileOutputStream("G:\\address.ser", true);
ObjectOutputStream oos = new ObjectOutputStream(fout);
){
oos.writeObject(myClassList);
} catch (Exception ex) {
ex.printStackTrace();
}
Simple program to write objects to file and read objects from file.
package program;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class TempList {
public static void main(String[] args) throws Exception {
Counter counter = new Counter(10);
File f = new File("MyFile.txt");
FileOutputStream fos = new FileOutputStream(f);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(counter);
oos.close();
FileInputStream fis = new FileInputStream(f);
ObjectInputStream ois = new ObjectInputStream(fis);
Counter newCounter = (Counter) ois.readObject();
System.out.println(newCounter.count);
ois.close();
}
}
class Counter implements Serializable {
private static final long serialVersionUID = -628789568975888036 L;
int count;
Counter(int count) {
this.count = count;
}
}
After running the program the output in your console window will be 10 and you can find the file inside Test folder by clicking on the icon show in below image.
I think you have to write each object to an own File or you have to split the one when reading it.
You may also try to serialize your list and retrieve that when deserializing.
if you serialize the whole list you also have to de-serialize the file into a list when you read it back. This means that you will inevitably load in memory a big file. It can be expensive. If you have a big file, and need to chunk it line by line (-> object by object) just proceed with your initial idea.
Serialization:
LinkedList<YourObject> listOfObjects = <something>;
try {
FileOutputStream file = new FileOutputStream(<filePath>);
ObjectOutputStream writer = new ObjectOutputStream(file);
for (YourObject obj : listOfObjects) {
writer.writeObject(obj);
}
writer.close();
file.close();
} catch (Exception ex) {
System.err.println("failed to write " + filePath + ", "+ ex);
}
De-serialization:
try {
FileInputStream file = new FileInputStream(<filePath>);
ObjectInputStream reader = new ObjectInputStream(file);
while (true) {
try {
YourObject obj = (YourObject)reader.readObject();
System.out.println(obj)
} catch (Exception ex) {
System.err.println("end of reader file ");
break;
}
}
} catch (Exception ex) {
System.err.println("failed to read " + filePath + ", "+ ex);
}
Supose you have the following method:
public static void writeToBinary(Object obj, String filename)
{
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
oos.writeObject(obj);
} catch (Exception e) {
e.printStackTrace();
} finally{
try{
if (oos != null) oos.close ();
}catch (Exception e){
e.printStackTrace();
}
}
}
As you can see, the method writes an object to a binary file.
But now you want to rewrite the same method to allow appending objects to the same file.
Ok, you look at the java documentation and you see that you have to add a parameter with value true to the FileOutputStream:
oos = new ObjectOutputStream(new FileOutputStream(filename, true));
You compile but, whoops!, it seems that it continues overriding the file.
Well, the problems begin. After searching in google you read that you have to use the SAME ObjectOutputStream to append objects to the same file. You want to have a function that every time you call it, it appends an object. I.e. :
writeToBinary("a", filename);
writeToBinary("b", filename);
But as I said before, you have to use the same ObjectOutputStream.
Solution 1:
ObjectOutputStream out = getOutputStream (filename);
writeToBinary("a", out);
writeToBinary("b", out);
writeToBinary("c", out);
out.close ();
This is very ugly because I want to hide the usage of streams.
Is there any other solution?
EDIT: The method is static. It is inside an utility class where all methods are static.
EDIT2: SOLVED! Appending to an ObjectOutputStream. See accepted answer to my question.
Thanks.
Solved.
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
public class Test{
private static String filename = "test";
public static void main(String[] args) {
writeToBinary (filename, "a", true);
writeToBinary (filename, "b", true);
writeToBinary (filename, "c", true);
readFromBinaryFile (filename);
}
public static void writeToBinary (String filename, Object obj, boolean append){
File file = new File (filename);
ObjectOutputStream out = null;
try{
if (!file.exists () || !append) out = new ObjectOutputStream (new FileOutputStream (filename));
else out = new AppendableObjectOutputStream (new FileOutputStream (filename, append));
out.writeObject(obj);
out.flush ();
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (out != null) out.close ();
}catch (Exception e){
e.printStackTrace ();
}
}
}
public static void readFromBinaryFile (String filename){
File file = new File (filename);
if (file.exists ()){
ObjectInputStream ois = null;
try{
ois = new ObjectInputStream (new FileInputStream (filename));
while (true){
String s = (String)ois.readObject ();
System.out.println (s);
}
}catch (EOFException e){
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (ois != null) ois.close();
}catch (IOException e){
e.printStackTrace ();
}
}
}
}
private static class AppendableObjectOutputStream extends ObjectOutputStream {
public AppendableObjectOutputStream(OutputStream out) throws IOException {
super(out);
}
#Override
protected void writeStreamHeader() throws IOException {}
}
}
oos = new ObjectOutputStream(new FileOutputStream(filename, true)); You
compile but, whoops!, it seems that it
continues overriding the file.
That does not make sense. The FileOutputStream is a streams that appends to the existing file, so it will not overwite the file. Check it.
The problem is that a stream cannot be closed and reopened to serialize several objects. Run the following and compare the resulting files to check it.
public class XX {
public static void writeToBinary(Object obj, String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true));
oos.writeObject(obj);
oos.close();
}
public static void writeToBinary2(Object obj1, Object obj2,String filename) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename,true));
oos.writeObject(obj1);
oos.writeObject(obj2);
oos.close();
}
public static void main(String[] args) throws Exception {
String s1= "hi, just trying";
String s2= "bye bye cruel world";
String filename = "/temp/f.dat";
String filename2 = filename + ".2" ;
writeToBinary(s1, filename);
writeToBinary(s2, filename);
writeToBinary2(s1, s2,filename2);
ObjectInputStream fin = new ObjectInputStream(new FileInputStream(filename)); // oops... works with filename2
Object x1 = fin.readObject();
Object x2 = fin.readObject();
System.out.println(x1);
System.out.println(x2);
}
}
Write a helper class. In constructor it will instantiate an output stream for a particular file name. Then using some append() or writeToBinary() method it will append the data. on method close() there will be flush() and close() calls on the stream.
BinaryWriteHelper helper = new BinaryWriteHelper("test.dat");
helper.writeToBinary("1");
helper.writeToBinary(2);
helper.close();
in BinaryWriteHelper :
public BinaryWriteHelper(String filename) {
this.stream = new ObjectOutputStream(new FileOutputStream(filename));
}
public close() {
// the cleanup here
}
Try this approach:
Write the object to a ByteArrayOutputStream.
Append the the size and contents of the ByteArrayOutputStream to a RandomAccessFile.
To load an object from the file, read the bytes that represent an Object into a ByteArrayInputStream and initialize an ObjectInputStream on this. The size field that was prepends each object byte sequence will come handy here.