import java.io.*; import java.util.zip.*; public Object readCompressedObject(String filename) { try { ZipInputStream zipin = new ZipInputStream(new FileInputStream(getDataFile(filename + ".zip"))); zipin.getNextEntry(); ObjectInputStream in = new ObjectInputStream(zipin); Object obj = in.readObject(); in.close(); return obj; } catch (FileNotFoundException e) { System.out.println("File not found!"); } catch (IOException e) { System.out.println("I/O Exception"); } catch (ClassNotFoundException e) { System.out.println("Class not found! :-("); e.printStackTrace(); } return null; //could not get the object } public void writeObject(Serializable obj, String filename) { try { ZipOutputStream zipout = new ZipOutputStream(new RobocodeFileOutputStream(getDataFile(filename + ".zip"))); zipout.putNextEntry(new ZipEntry(filename)); ObjectOutputStream out = new ObjectOutputStream(zipout); out.writeObject(obj); out.flush(); zipout.closeEntry(); out.close(); } catch (IOException e) { System.out.println("Error writing Object:" + e); } }What this basically does is compresses your serialized objects in zip files. I can't remember exactly what degree of compression I got from doing this, but it seems like it was on the order of 1/10th the file size.
-- Kawigi
What standard-java-type objects are you trying to serialize within your objects? Usually the Java documentation has a note somewhere if serialized objects under one implementation of a class will not be compatible with future releases. -- Kawigi
The objects I'm serializing are simple. Containing two doubles, two ints and one ArrayList containing even simpler objects consisting of only doubles and ints. Could it be some versioning problem with my own objects? I don't think so since I would then expect to see the failure without the packaging/unpackaging. -- PEZ
Hmmm... not sure what to say. The javadocs don't say anything about problems with serializing ArrayList objects... -- Kawigi
Well, it might be some aspect of Robocode that I have misunderstood. If "train" a development version robot and then package it and then run the packaged robot it seems unable to read the serialized objects. It doesn't matter that it is the same computer and JVM running. While using the development version there are no problems at all reading those objects. And the packaged robot has no problems reading its object files once it has reacreated them... -- PEZ
What do you mean with movement arrays? Like pattern matcher data?. Between rounds all pattern matchers do this I would guess. Between matches some do it. Nibbler is one. -- PEZ
yes, i mean pattern matcher data. Between rounds i 'store' the data by using static's. Now i am looking for a way to store the data at the end of a match and retreive it at the start of a new match. I have been looking into the JavaDoc?, but find Java's IO terribly complex with al those nested streams. The code on this page shows an example and works for a simple case, but after i started saving data from my targets i now get all kinds of "inconvertible types" errors. Isn't it possible to save int's and double's? -- Loki
PEZ, is your problem with the deserialisation of data (mentioned at CompressedSerialization) solved?
Sure you can just save primitive data types. Look at SittingDuck for one way of doing this. Nibbler uses SymbolicPatternMatching and saves the string. That's one more advantage of symbolic pattern matching. Yes, I still have problems with deserialization. I haven't looked in to it, but now it is starting to become a problem again. I haven't tried to use the serial version id thingy yet. If that doesn't work I'll go for externalization instead. Should be able to save some space that way also. -- PEZ
Found the solution for my "inconvertible types" errors: I am using ObjectInput/OutputStream as in the example. When reading data from file you have to cast the object into the desired object. Example:
StringBuffer pattern = (StringBuffer)in.readObject();When reading primitive types you have to use the appropriate methods from the ObjectInputStream? class. Example:
int historyCounter = in.readInt();-- Loki
New question: I found in the Robocode version info that the quota for files is 200k (as for robocode version 1.06). How can you prevent running out of 'disk space' -- Loki
The only way must be to check if what you want to write fits in the space left and then you have to either save less or delete something from your directory. Check TheArtOfWar code, it handles this situation. -- PEZ
Did any one try this with jdk1.4.2 beta. I have some problems to save or load data. I tried Marshmallow as well it also fails. Any ideas? --SSO?
What problems do you encounter? I use jdk1.4.1 b.t.w. --Loki
In what way does Marshmallow fail? -- PEZ
Mainly it's security problem. My bot has the same problem. Here is the exception
pez.Marshmallow 1.5.3: Exception: java.security.AccessControlException?: Preventing pez.Marshmallow 1.5.3 from access: (java.io.FilePermission? E:\java\robocode\robots\pez read): You may only read files in your own root package directory. java.security.AccessControlException?: Preventing pez.Marshmallow 1.5.3 from access: (java.io.FilePermission? E:\java\robocode\robots\pez read): You may only read files in your own root package directory.
at robocode.security.RobocodeSecurityManager?.checkPermission(RobocodeSecurityManager?.java:314) at java.lang.SecurityManager?.checkRead(SecurityManager?.java:863) at java.io.File.exists(File.java:678) at java.io.Win32FileSystem?.canonicalize(Win32FileSystem?.java:358) at java.io.File.getCanonicalPath?(File.java:513) at java.io.File.getCanonicalFile?(File.java:534) at robocode.peer.robot.RobotFileSystemManager?.getReadableDirectory?(RobotFileSystemManager?.java:110) at robocode.security.RobocodeSecurityManager?.checkPermission(RobocodeSecurityManager?.java:299) at java.lang.SecurityManager?.checkRead(SecurityManager?.java:863) at java.io.File.exists(File.java:678) at java.io.Win32FileSystem?.canonicalize(Win32FileSystem?.java:358) at java.io.File.getCanonicalPath?(File.java:513) at java.io.File.getCanonicalFile?(File.java:534) at robocode.peer.robot.RobotFileSystemManager?.getWritableDirectory?(RobotFileSystemManager?.java:125) at robocode.AdvancedRobot.getDataFile?(AdvancedRobot.java:363) at pez.Marshmallow.writeObject(Unknown Source) at pez.Marshmallow.saveStatistics(Unknown Source) at pez.Marshmallow.onRobotDeath?(Unknown Source) at robocode.peer.robot.EventManager?.onRobotDeath?(EventManager?.java:598) at robocode.peer.robot.EventManager?.processEvents(EventManager?.java:742) at robocode.peer.RobotPeer?.tick(RobotPeer?.java:1024) at robocode.AdvancedRobot.execute(AdvancedRobot.java:186) at pez.Marshmallow.run(Unknown Source) at robocode.peer.RobotPeer?.run(RobotPeer?.java:616) at java.lang.Thread.run(Thread.java:534)
--SSO?
And does SittingDuck have the same problem? -- PEZ
NO! --SSO?
Strange, I was almost sure it should... -- PEZ
Do you use getDataFile?() or whatever? -- Kawigi
I had the same problem. Solved it by
while (!dataIsLoaded?) {
try { tryToReadData?; dataIsLoaded? = true; } catch (AnyException? e) {}}
this looks like something that should never work, but it does. about every 10th try to read anthing, the exception occurs. randomly. so i just try to read the file ovr and over again until robocode gives up, and i get the file. same for saving. -HoD
Wait, I'm confused; how come it lets you catch an AccessControlException? and allows the bot to keep going? When I was testing out the effects of referencing GL classes on regular Robocode, even if I caught the AccessControlException?, Robocode would still disable my robot and kill its thread.
Also, does that zipping code write the .zip header with the file, or does it just write the zip data bare? Because if it is, you're saving a zip header for nothing. I mean it could only be a few bytes per file, but still... -- Vuen
Such is true. You can also be classy and make a zip file with a file in it for each enemy if you wanted. Or you can go SandboxMini's route (and presumably SandboxDT's) and use a GZip compression thingy. (I don't know if that changes the header stuff). Or you could be REALLY like Paul Evans and make your own complete compression scheme. -- Kawigi
I am suffering with the java.security.AccessControlException? problem since upgrading to Java version 1.4.2. I have observed the following...
My present solution to work around the problem is to do all file reads in round 1, storing the data in statics - catching the exception and re-reading if necessary. At worst you will loose round 1 because of being disabled. For any other file I/O perform at then end of the round - retyring if the output is important.
-- Paul Evans