在游戏运行的过程中,往往会有来电啊,来短信,所以对这些机制的处理也是游戏编程中的一个重要部分,大多数情况下使用文件存储的形式可以完全实现游戏中数据的存储和读取。

首先回顾下Java中对文件的操作:

比如想实现存储一个对象数组放入文件中并且需要对其进行分隔,Java中有两种实现方式:(1)以文本格式保存数据(2)以二进制格式保存数据。比如我们想实现存储一个Employee记录的数组。并且采用分隔格式存储Employee记录的一个数组;存储的格式为:


Harry Hacker|355500|1989|10|1 
 
 
 

       Carl Cracker|75000|1987|12|15 
 
 
 

       Tony Tester|38000|1990|3|15 
 
 
 

   写入记录:采用PrintWriter类。 
 
 
 

         public void writeData(PrintWriter out) throws IOException 
   
 
   

        { 
   
 
   

           GregorianCalendar calendar = new GregorianCalendar(); 
   
 
   

           calendar.setTime(hireDay); 
   
 
   

           out.println(name + "|" 
   
 
   

              + salary + "|" 
   
 
   

              + calendar.get(Calendar.YEAR) + "|" 
   
 
   

              + (calendar.get(Calendar.MONTH) + 1) + "|" 
   
 
   

              + calendar.get(Calendar.DAY_OF_MONTH)); 
   
 
   

        }


读出数据:java.util.StringTokenizer。如果不指定分隔符,默认为\t\n\r\f

该类的几个方法:

StringTokenizer(String str, String delim)//(delim分隔符的集合) 
 

   StringTokeizer(String str) 
 
 
 

   boolean hasMoreTokens()(判断字符串中是否含有子字符串) 
 
 
 

   String nextToken()( 
  取出下一个子字符串) 
 
 
 

   int countTokens() 
  
 ( 
  判断有多少个被分隔符分开的字符串) 
  
 

   while(tokenizer.hasMoreTokens()) 
 
 
 

   { 
 
 
 

   String token = tokenizer.nextToken(); 
 
 
 

       // process token 
 
 
 

   }


二进制方式:


    -当存储大量Employee对象时,采用文本方式保存每个对象的长度不等,因此很难实现随机存取;



    -采用二进制存储方式让每条记录具有相同的长度;



    -可以通过RandomAccessFile实现随机存取;



    -简单数据类型通过DataOutput接口的相关方法可以实现定长写入文件;



    -String类型的数据长度不定,需提供方法将字符串以固定长度写入文件;



    -自定类DataIO实现定长字符串的输入与输出;



l实现字符串定长写入



   -方法以参数size指定字符串写入的长度,如果不够,以0补充;



public static void writeFixedString(String s, int size, DataOutput out) 
   
 
   

           throws IOException// 
    静态的类方法,不希望调用的时候再次实例化  
   
 
   

        { 
   
 
   

           for (int i = 0; i < size; i++)// 
    size以字符为单位1,一个16位  
   
 
   

           {  
   
 
   

              char ch = 0; 
   
 
   

              if (i < s.length()) ch = s.charAt(i); 
   
 
   

              out.writeChar(ch);// 
    将string写入out的输出流中  
   
 
   

           } 
   
 
   

        }// 
    一般将size设置足够长

l 实现定长字符串输入



   -方法从输入流中读取字符,直到读取了size个字符或者遇到一个0值的字符为止,并跳过输入域中其他的0值;


public static String readFixedString(int size, DataInput in) 
 
 
 

         throws IOException 
 
 
 

      {  
 
 
 

         StringBuilder b = new StringBuilder(size); // 
  stringBuilder带有一定缓冲区,读取时以单个字符读入 
 
 
 

         int i = 0;// 
  用I计数,统计读入数据数  
 
 
 

         boolean more = true; 
 
 
 

         while (more && i < size)// 
  用户是否读完数据和是否达到固定长度  
 
 
 

         { 
     
 
 
 

            char ch = in.readChar(); 
 
 
 

            i++; 
 
 
 

            if (ch == 0) more = false; 
 
 
 

            else b.append(ch); 
 
 
 

         } 
 
 
 

         in.skipBytes(2 * (size - i)); 
 
 
 

         return b.toString();// 
  将stringbuilder转换成字符串返回  
 
 
 

      }


l 写入定长的记录



public void writeData(DataOutput out) throws IOException 
   
 
   

        { 
   
 
   

           DataIO.writeFixedString(name, NAME_SIZE, out); 
   
 
   

           out.writeDouble(salary); 
   
 
   

           GregorianCalendar calendar = new GregorianCalendar(); 
   
 
   

           calendar.setTime(hireDay); 
   
 
   

           out.writeInt(calendar.get(Calendar.YEAR)); 
   
 
   

           out.writeInt(calendar.get(Calendar.MONTH) + 1); 
   
 
   

           out.writeInt(calendar.get(Calendar.DAY_OF_MONTH)); 
   
 
   

        } 
   
 
   
 
      public void readData(DataInput in) throws IOException  
     
 
     
 
         {  
     
 
     
 
            name = DataIO.readFixedString(NAME_SIZE, in);  
     
 
     
 
            salary = in.readDouble();  
     
 
     
 
            int y = in.readInt();  
     
 
     
 
            int m = in.readInt();  
     
 
     
 
            int d = in.readInt();  
     
 
     
 
            GregorianCalendar calendar = new GregorianCalendar(y, m - 1, d); 
     
 
     
 
            hireDay = calendar.getTime();  
     
 
     
 
         }