PrintService属性的Java序列化

时间:2013-05-24 00:44:04

标签: java serialization deserialization

从我的搜索中,我认为this是对我的问题的一个很好的总结。也许,我正在序列化或反序列化对象错误?或者,如果序列化是正确的,我的问题是否有修复/解决方法?

我一直在使用this作为Win32MediaSize类的参考。关于引用的Win32MediaSize类,我有另一个稍微相关的问题。请参阅从1640开始的代码,它是静态初始化程序。我试图重现,所以我可以看到执行顺序:

public clsss Why {

  static {
    String a = "Hello";
  }

  public class Not {
    static { // gives me a Cannot define static initializer in inner type error
      String b = "World";
    }
  }
}

这不是主要问题,但如果有人能在这里阐明一点,那将会很棒。我个人认为它是Win32MediaSize中的问题,但我不知道为什么。我也尝试了他们在第85行和双括号上所做的事情,但都没有效果。删除关键字static确实可以解决错误,但我认为根据我的理解会产生不同的行为。

基本问题是我需要为每个PrintService执行getSupportedAttributeValues,以便读取序列化数据,这会破坏序列化数据的目的。序列化数据的原因是因为getSupportedAttributeValues需要很长时间才能完成(40+秒)。

以下是例外情况(valuerange根据PrintService已加载的情况而有所不同 - 在另一个线程中加载的实际程序中;请参阅this参考):

java.io.InvalidObjectException: Integer value = 124 not in valid range 0..3for class class sun.print.Win32MediaSize
    at javax.print.attribute.EnumSyntax.readResolve(EnumSyntax.java:184)
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadResolve(ObjectStreamClass.java:1056)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1761)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at java.util.HashMap.readObject(HashMap.java:1030)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at com.iii.print.PrintServiceLoader.readCachedData(PrintServiceLoader.java:355)
    at com.iii.print.PrintServiceLoader.main(PrintServiceLoader.java:420)

这是相关的代码位:

方法works()fails()是我遇到的问题。

void works() {
  HashMap<String, Object> m = null;
  HashMap<String, Object> mpa = null;
  doLookup(); // this is what causes the following call to not fail
  m = readCachedData( "a" );
  mpa = readCachedData( "b" );
}

void fails() {
  /* Assuming the files have already been created */
  HashMap<String, Object> m = null;
  HashMap<String, Object> mpa = null;
  m = readCachedData( "a" ); // this fails (see exception)
  mpa = readCachedData( "b" ); // this will work just fine
}


void doLookup() {
  PrintService[] psList = PrintServiceLookup.lookupPrintServices( DocFlavor.SERVICE_FORMATTED.PRINTABLE, null );

  HashMap<String, Object> cachedMedia = new HashMap<String, Object>();
  HashMap<String, Object> cachedMediaPrintableArea = new HashMap<String, Object>();
  for ( PrintService ps : psList ) {
    Object media = ps.getSupportedAttributeValues( Media.class, null, null );
    Object mediaPrintableArea = ps.getSupportedAttributeValues( MediaPrintableArea.class, null, null );
    cachedMedia.put( ps.getName(), media );
    cachedMediaPrintableArea.put( ps.getName(), mediaPrintableArea );
  }

  writeCachedData( "a", cachedMedia );
  writeCachedData( "b", cachedMediaPrintableArea );
}

boolean writeCachedData( String filename, Map<String, Object> data ) {
  boolean successful = true;

  if ( filename != null && !filename.isEmpty() && data != null && !data.isEmpty() ) {
    FileOutputStream fileOutStream = null;
    ObjectOutputStream objOutStream = null;

    try {
      fileOutStream = new FileOutputStream( filename );
      objOutStream = new ObjectOutputStream( fileOutStream );
      objOutStream.writeObject( data );
    } catch ( FileNotFoundException e ) {
      e.printStackTrace();
      successful = false;
    } catch ( IOException e ) {
      e.printStackTrace();
      successful = false;
    } finally {
      try {
        if ( objOutStream != null ) {
          objOutStream.close();
        }
      } catch ( IOException e ) {
        e.printStackTrace();
        successful = false;
      }
      try {
        if ( fileOutStream != null ) {
          fileOutStream.close();
        }
      } catch ( IOException e ) {
        e.printStackTrace();
        successful = false;
      }
    }

  } else {
    successful = false;
  }

  return successful;
}

Map<String, Object> readCachedData( String filename ) {
  Map<String, Object> cachedData = null;

  if ( filename != null && !filename.isEmpty() ) {
    File f = new File( ".", filename );
    if ( f.exists() ) {
      FileInputStream fileInStream = null;
      ObjectInputStream objInStream = null;

      try {
        fileInStream = new FileInputStream( f );
        objInStream = new ObjectInputStream( fileInStream );
        cachedData = (Map<String, Object>) objInStream.readObject();
      } catch ( FileNotFoundException e ) {
        e.printStackTrace();
      } catch ( IOException e ) {
        e.printStackTrace();
      } catch ( ClassNotFoundException e ) {
        e.printStackTrace();
      } finally {
        try {
          if ( fileInStream != null ) {
            fileInStream.close();
          }
        } catch ( IOException e ) {
          e.printStackTrace();
        }
        try {
          if ( objInStream != null ) {
            objInStream.close();
          }
        } catch ( IOException e ) {
          e.printStackTrace();
        }
      }
    }
  }

  return cachedData;
}

正如您所知,我使用的是Windows 7 x64并使用jdk 1.6.0_31。如果我遗漏了相关信息,请告诉我。

1 个答案:

答案 0 :(得分:1)

关于你的第一个问题:

class不应该是公共静态的,不是公共的。

public class Test {

    static {

    }

    public static class Not {
        static { 
            String b = "World";
        }
    }
}