User:Pedersen/Code Samples/Persistence
Jump to navigation
Jump to search
I have overhauled my persistence implementation. One addition I have made is allowing logging that does not wait until the end of the match before posting anything (through the getPrintStream( filename ) method). All methods are static.
If the dataDirectory value is not provided, all calls will return null instead of the desired content, preventing file I/O (and the potential for the CanonCaches bug). In the setup of my bot I have the following line:
if( Constraints.allowFileIO ) Persistence.setDataDirectory( this.getDataDirectory() );
The Console class manages printing of text and exceptions to System.out, which is the tank's log / debug window.
Modify to taste.
/** * Stores and retrieves data from the local cache. * Data may be targeting or movement statistics, debug information, etc. * * @author Martin Alan Pedersen */ public class Persistence { //::////////////////////////////////////// //:: Static Methods //::////////////////////////////////////// public static void setDataDirectory( File newDataDirectory ) { Persistence.dataDirectory = newDataDirectory; } /** * Creates a PrintStream that is compatible with RoboCode's file permissions management. * * @param filename the name of the data directory file to be written to * * @return a print stream associated with the file */ public static PrintStream getPrintStream( String filename ) { PrintStream outputStream = null; File dataFile = getDataFile( filename ); if( dataFile != null ) { try { outputStream = new PrintStream( new RobocodeFileOutputStream( dataFile ) ); } catch( Exception ex ) { Console.getInstance().log( "Exception thrown opening PrintStream [" + filename + "]." ); Console.getInstance().log( ex ); if( outputStream != null ) outputStream.close(); } } return outputStream; } /** * Places the contents of a file in a CharBuffer. * * @param filename the name of the data directory file to be read from * * @return a CharBuffer containing the entire contents of the file */ public static CharBuffer getFileContents( String filename ) { CharBuffer fileContents = null; File dataFile = getDataFile( filename ); if( dataFile != null ) { FileReader inputStream = null; try { inputStream = new FileReader( dataFile ); CharBuffer buffer = CharBuffer.allocate( (int)dataFile.length() ); if( inputStream.read( buffer ) == (int)dataFile.length() ) { fileContents = buffer; } } catch( Exception ex ) { Console.getInstance().log( "Exception thrown reading contents of file [" + filename + "]." ); Console.getInstance().log( ex ); } finally { try { if( inputStream != null ) inputStream.close(); } catch( IOException ex ) { Console.getInstance().log( "Exception thrown closing input stream [" + filename + "]." ); Console.getInstance().log( ex ); } } } return fileContents; } /** * Writes a list of strings to a file. * * @param list the list of strings * @param filename the name of the file to write to */ public static void writeListToFile( String filename, List list ) { PrintStream outputStream = getPrintStream( filename ); if( outputStream != null ) { try { Iterator iterator = list.iterator(); while( iterator.hasNext() ) { outputStream.println( encrypt( (String) iterator.next() ) ); } } catch( Exception ex ) { Console.getInstance().log( "Exception thrown writing list to file" ); Console.getInstance().log( ex ); } finally { if( outputStream != null ) outputStream.close(); } } } /** * Reads a file and converts each line into a list entry. * * @param filename the name of the file to read. * * @return the lines of the file in the form of a list */ public static List readListFromFile( String filename ) { List list = new ArrayList(); CharBuffer fileContents = getFileContents( filename ); if( fileContents != null ) { String buffer = fileContents.toString(); int indexStart = 0; int indexEnd = buffer.indexOf( "\n", indexStart ); while( indexEnd != -1 ) { list.add( decrypt( buffer.substring( indexStart, indexEnd ) ) ); indexStart = indexEnd + 1; indexEnd = buffer.indexOf( "\n", indexStart ); } } return list; } /** * Gets a data directory file. * * @param filename the name of the data file * * @return a File object associated with the data file */ private static File getDataFile( String filename ) { File dataFile = null; if( dataDirectory != null ) { dataFile = new File( dataDirectory, mangle( filename ) ); } if( dataFile == null ) { Console.getInstance().log( "Access to file [" + filename + "] is denied." ); } return dataFile; } /** * Converts readable data into encrypted data. * * @param readable the readable data * * @return encrypted data */ private static String encrypt( String readable ) { String unreadable = null; unreadable = readable; // placeholder return unreadable; } /** * Converts encrypted data into readable data. * * @param unreadable encrypted data * * @return readable data */ private static String decrypt( String unreadable ) { String readable = null; readable = unreadable; // placeholder return readable; } /** * Converts a string into a file-friendly one. Intended for converting tank names. * * @param original the original name * * @return the converted filename */ private static String mangle( String original ) { StringBuffer buffer = new StringBuffer(); char character; for( int i = 0; i < original.length(); i++ ) { character = original.charAt( i ); if( ( character > 47 ) && ( character < 58 ) ) buffer.append( character ); else if( ( character > 64 ) && ( character < 91 ) ) buffer.append( character ); else if( ( character > 96 ) && ( character < 123 ) ) buffer.append( character ); } buffer.append( ".txt" ); return buffer.toString(); } //::////////////////////////////////////// //:: Static Variables //::////////////////////////////////////// private static File dataDirectory = null; }