PrintService 属性的 Java 序列化

标签 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 秒以上)。

这是一个异常(exception)(范围根据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。如果我遗漏了相关信息,请告诉我。

最佳答案

关于你的第一个问题:

class 不应该是 public static,而不是 public。

public class Test {

    static {

    }

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

关于PrintService 属性的 Java 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726160/

相关文章:

java - 传递 MethodHandles.lookup().lookupClass() 与传递 Class<?> 到 getLogger 方法

c# - System.Text.Json.JsonSerializer.Serialize 返回空 Json 对象 "{}"

java - 序列化 ArrayList android 不起作用

c# - wcf 客户端在反序列化期间忽略派生类型

java - 在模式中动态添加 JLabel 但最后一个无法正常工作

java - 连接到网站并保持 session ?

XML 序列化 - 客户端缺少命名空间前缀

Java 序列化与继承?

Java:本地缓存和更改

java - 如何在 eclipse 中添加gradle?