I wrote a object using ObjectOutputStream, and read it using ObjectInputStream, and tested it , I get the expected result. But when write the object in other machine, read it in my computer, the read object's members are empty. Could someone help me? thanks
public class TrustNet implements Serializable{
public double[][] trusts;
public double avg = 0;
public TrustNet(int size){
trusts = new double[size][size];
}
public void writeToFile(String fileName){
try(ObjectOutputStream writer = new ObjectOutputStream(new FileOutputStream(fileName))){
writer.writeObject(this);
writer.flush();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static TrustNet readFromFile(String fileName){
try(ObjectInputStream writer = new ObjectInputStream(new FileInputStream(fileName))){
return (TrustNet) writer.readObject();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
}
It took me a day to figure out what's going on. I think I finally have the answer. May be it will help other people having similar problem.
In my case, the problem was due of using ProGuard.
ProGuard minifyed the code, giving new shorts names to fields, like
a, b, c, etc.
When serializing, the names of fields get stored into the stream. When reading the stream, the names must match.
When I minifyed code the last time (for the new Production version of the app), ProGuard gave different names to fields (in my case it
was due of changed ProGuard settings, but may be due of other
reasons too, not sure if ProGuard guarantee the same names every
time).
As result, when I deserialize the object in the new version, because of the names are not match, all the fields set to default values.
Related
I'm making a new game and I wanna make a coins collector to, later, buy things with those coins. I'm using eclipse.
void save() {
try {
PrintWriter out = new PrintWriter("coins.txt");
out.write(Integer.toString(nmonedas));
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
void load() {
StringBuffer texto=new StringBuffer();
try {
int c;
#SuppressWarnings("resource")
FileReader entrada=new FileReader("coins.txt");
while((c=entrada.read())!=-1){
texto.append((char)c);
}
}
catch (IOException ex) {}
labelshow.setText(texto.toString());
}
I have this code but i cant plus the info. NEED HELP PLS
Well, the thing is, I'm doing a game in eclipse and I want you to collect coins and keep them in a file.
They are collected perfectly and stored in the file, but when I start the game again I want them to be collected but they add up with the previous ones
I assume you are referring to appending text to a .TXT file. If so, you can use something like this:
Files.write(Paths.get("Path to text file here"), "Content".getBytes(), StandardOpenOption.APPEND);
I would put the above in a TRY CATCH block. Also look into PrintWriter as this may be more appopriate to what you need it for as it allows you to continuously write to the file.
I have been frustrated for almost 2 days trying to find the flaw because the registry.delete() method does not delete the file "Registry.txt". I'm working with a GUI, and every time I click on a row of a JTable and then click on the "Ban" button, it does not delete the file "Registry.txt", and it does not write either! However, if I do it from another class, like the class that has the main() method, it clears properly. What I wanted to do is delete a line from the Registry.txt, writing in another .txt file all of the lines that did not contain a certain String name, and then rename it to the name Registry.txt. I do not know what is happening. Below is my code:
ActionListener ban = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int fila = table.getSelectedRow();
String nombre = (String) modelo.getValueAt(fila, 0);
modelo.removeRow(fila);
try {
removeUser(nombre);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
};
btnBanear.addActionListener(ban);
...
public void removeUser(String nombre) throws IOException {
String lee = null;
String usuario = "";
CharSequence aux = nombre;
try {
registro = new File("Registro.txt");
tempFile = new File("Registro1.txt");
lector = new BufferedReader(new FileReader(registro));
fw = new FileWriter(tempFile);
writer = new BufferedWriter(fw);
} catch (FileNotFoundException ex) {
System.out.println(ex.getMessage());
} catch (IOException ex) {
System.out.println(ex.getMessage());
} catch (NullPointerException e) {
System.out.println(e.getMessage());
}
while ((lee = lector.readLine()) != null) {
System.out.println(aux);
if (lee.contains(nombre)) {
continue;
} else {
writer.write(lee);
}
}
lector.close();
fw.close();
writer.close();
registro.delete();
}
I don't think we have quite enough data to see exactly why this is happening, but I can give you some strong suspicions.
File.delete() throws four possible exceptions; three of which apply here. NoSuchFileException (worth specifically checking for), IOException, and SecurityException. NoSuchFileException is derived from IOException and would be caught anyway; though you might want to catch for it still as casting it to an IOException is going to remove relevant data. SecurityException is generally when a security manager gets in the way, which happens all the time on web-based programs. I'm wondering if your file is some kind of an applet or its modern equivalent, the web application? SecurityException is a RuntimeException, so you don't have to catch for it, but you can and probably should. That would explain worlds.
Lastly, you can also use File.deleteIfExists(). This returns a value of true if the file was actually present to be deleted, and false if it could not be found. Worth looking into, because if your path is getting skewed and the file can't be found at the provided location, then it won't be deleted. It's reasonable to think that your program might have a different working directory than you're thinking it does. This is more or less the same as checking for NoSuchFileException, though.
You might even check your working directory, to be sure, with System.out.println(System.getProperty("user.dir")).
My money is on SecurityException or the path being wrong. However, if I'm wrong about this, it would be nice if you could show us your other button code, because there could be a relevant problem there, too.
I've MyQ class
class MyQ{
Queue<Request> q = new PriorityQueue<Request>(7, new SortRequest());
QueueStorage qStorage = new QueueStorage();
public void addRequest(int siteId, int timeStamp){
try{
q = qStorage.readRequestQ();
q.add(new Request(sId, tStamp));
qStorage.writeRequestQ(q);
}catch(Exception e){
e.printStackTrace();
}
//similarly deleteRequest() and showRequest() method follows.
}
My Request class contains two fields int id and int count along with setters and getters.
SortRequest class is something like this:
class SortRequest implements Comparator<Request>, Serializable{
public int compare(Request r1, Request r2) {
if(r1.getCount()!=r2.getCount())
return new Integer(r1.getCount()).compareTo(r2.getCount());
if(r1.getId()!=r2.getId())
return new Integer(r1.getId()).compareTo(r2.getId());
return 0;
}
}
And QStorage class is something like:
class QStorage{
Queue<Request> readReqQ = new PriorityQueue<Request>(7, new SortRequest());
public Queue<Request> readRequestQ() {
try{
FileInputStream fin = new FileInputStream("/home/winn/requestQ.ser");
ObjectInputStream ois = new ObjectInputStream(fin);
readReqQ = (Queue)ois.readObject();
}
catch(Exception e){
return null;
}
return readReqQ;
}
public void writeRequestQ(Queue<Request> rq){
Queue<Request> requestQ = rq;
try{
FileOutputStream fos = new FileOutputStream("/home/winn/requestQ.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(requestQ);
System.out.println("done");
}catch(Exception e){
e.printStackTrace();
}
}
}
And also I am storing this queue in file after every add/poll operation using Object input/output stream. While adding element I am first reading stored entries and then adding new entry and again storing it back.
Constraint is that id should be unique, count can be same/different for two or more ids.
So I'm performing sorting on count parameter, but in case if count is same then I should get the sort order such that lower id should precede higher one.
I tried initially this program on my linux system, where it was working properly and correctly giving sort order as per my expectation. But then somehow I deleted all class files and also created a new file for storing, and now same code(after recompiling) giving me completely strange results. Its not even sorting based on count parameter. Why this is so?
I then tried the same code on my windows 7 system, its again started producing correct results.
Why such a strange behaviour ?
Please help. Thanks.
You aren't closing the ObjectOutputStream. I expect that you are getting a StreamCorruptedException or an EOFException instead of the behaviour you so vaguely describe. Or that you are ignoring such exceptions and proceeding with your code anyway.
I have saved an arrayList into a binary file by using serialastion. How do I now retrieve this data from the binary file?
This is the code I have used for serialisation
public void createSerialisable() throws IOException
{
FileOutputStream fileOut = new FileOutputStream("theBkup.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(allDeps);
options();
}
and this the code I am trying to use for deserialization of the arrayList:
public void readInSerialisable() throws IOException
{
FileInputStream fileIn = new FileInputStream("theBKup.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
try
{
ArrayList readob = (ArrayList)oi.readObject();
allDeps = (ArrayList) in.readObject();
}
catch (IOException exc)
{
System.out.println("didnt work");
}
}
allDeps is the declared array list in the classes constructer. Im trying to save the arrayList from the file to the arrayList declared in this class.
Your code is mostly correct, but there is one mistake and a couple of things that might make it work better. I've highlighted them with asterisks (since, apparently, I can't make them bold in 'code' mode).
public void createSerialisable() throws IOException
{
FileOutputStream fileOut = new FileOutputStream("theBkup.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(allDeps);
**out.flush();** // Probably not strictly necessary, but a good idea nonetheless
**out.close();** // Probably not strictly necessary, but a good idea nonetheless
options();
}
public void readInSerialisable() throws IOException
{
FileInputStream fileIn = new FileInputStream("theBKup.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
try
{
**// You only wrote one object, so only try to read one object back.**
allDeps = (ArrayList) in.readObject();
}
catch (IOException exc)
{
System.out.println("didnt work");
**exc.printStackTrace();** // Very useful for findout out exactly what went wrong.
}
}
Hope that helps. If you still see a problem then make sure you post the stack trace and a complete, self-contained, compilable example that demonstrates the problem.
Note that I've assumed that allDeps contains objects that are actually Serializable and that your problem is in readInSerialisable rather than in createSerialisable. Again, a stack trace would be extremely helpful.
I'm creating a basic 2D game (well a game engine) and I've currently been developing the file formats for my data. Of course, for this game to run, I will need cache. I find it quite unprofessional to leave all the data for the game to not be in a single file (well not necessarily, as long as the files are in a cache format of some kind).
So that's why I've came here to ask. I was thinking of doing a zip file but I feel like that isn't the best way at all. I was also thinking of doing another binary writer which will have headers (type of file, "location") and an enclosing tag for each of the files so it would be easy to interpret. But I felt like that was too inefficient.
So please, do you have any ideas?
Note: This game engine is really just for learning purposes.
tl;dr I need an efficient way to store data such as images for my game I'm making.
You can store any object as .dat file:
public class MyGame implements Serializable
{
private static void saveGame(ObjectType YourObject, String filePath) throws IOException
{
ObjectOutputStream outputStream = null;
try
{
outputStream = new ObjectOutputStream(new FileOutputStream(filePath));
outputStream.writeObject(YourObject);
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
}
catch(IOException ex)
{
ex.printStackTrace();
}
finally
{
try
{
if(outputStream != null)
{
outputStream.flush();
outputStream.close();
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
public static ObjectType loadGame(String filePath) throws IOException
{
try
{
FileInputStream fileIn = new FileInputStream(filePath);
ObjectInputStream in = new ObjectInputStream(fileIn);
return (ObjectType) in.readObject();
}
catch(FileNotFoundException ex)
{
ex.printStackTrace();
}
catch(IOException ex)
{
ex.printStackTrace();
}
}
}
I don't think that zip is the wrong way. It is a rather good way. Just put everything in a jar-File. You will even be able to use a classloader to load it.
For pragmatic reasons, I would recommend using multiple files but putting them all in a subdirectory in temp.
But if part of your learning exercise is related to this topic, here are my suggestions:
First, stay away from any format like ZIP, where there is a heavy penalty for deleting, updating, adding, jumping. Even with the index files of a JAR, they are poor for anything other than compression.
So you can read up on file systems. Essentially, you are writing a file system where the 'disk' is just a binary file. That should give you a high level idea of allocation tables, etc. In order to implement such a design, you need read/write access to the underlying file; look at java.io.RandomAccessFile
Finally, if you are willing to use Java7, you can play with the new filesystem SPIs.