简体   繁体   English

Java PrintService属性的序列化

[英]Java Serialization of PrintService Attributes

From my search, I think this is a pretty good summary of my problem. 从我的搜索中,我认为是我问题的一个很好的总结。 Perhaps, I'm serializing or de-serializing the objects wrong? 也许,我正在对对象进行序列化或反序列化吗? Or if the serialization is correct, is there a fix/workaround to my issue? 或者,如果序列化是正确的,是否有针对我的问题的修复/解决方法?

I've been using this as reference to the Win32MediaSize class. 我一直在使用作为Win32MediaSize类的引用。 I've got another slightly related question regarding the referenced Win32MediaSize class. 关于引用的Win32MediaSize类,我还有另一个稍微相关的问题。 See the code that begins at 1640 which is the static initializer. 请参阅从1640开始的代码,它是静态初始化程序。 I tried to reproduce that so I could see execution order: 我尝试重现该代码,以便可以看到执行顺序:

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";
    }
  }
}

This isn't the main issue but it would be great if someone could shed some light here. 这不是主要问题,但是如果有人可以在这里阐明一些观点,那就太好了。 I personally believe its the problem in Win32MediaSize but I don't know why. 我个人认为它是Win32MediaSize的问题,但我不知道为什么。 I also tried what they did on line 85 and double brackets and neither works. 我还尝试了他们在第85行和双括号中所做的工作,但均无济于事。 Removing the keyword static does resolve the error but I think that produces different behavior per my understanding. 删除关键字static确实可以解决错误,但是根据我的理解,我认为这会产生不同的行为。

The basic problem is that I need to execute getSupportedAttributeValues for each PrintService in order to read in serialized data which defeats the purpose of serializing the data. 基本问题是我需要为每个PrintService执行getSupportedAttributeValues以便读入序列化的数据,这违背了序列化数据的目的。 The reason for serializing the data is because getSupportedAttributeValues takes too long to finish (40+ seconds). 序列化数据的原因是因为getSupportedAttributeValues需要太长时间才能完成(超过40秒)。

Here's the exception (the value and range varies depending on far along the PrintService has loaded - in the actual program it's loading in another thread; see this for reference): 这是个例外( valuerangePrintService加载的range而异-在实际程序中它正在另一个线程中加载;请参阅作为参考):

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)

Here's the relevant code bits: 以下是相关的代码位:

Methods works() and fails() is what I'm having issues with. 我遇到的问题有方法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;
}

As you can tell, I'm on Windows 7 x64 and using jdk 1.6.0_31. 如您所知,我在Windows 7 x64上并使用jdk 1.6.0_31。 Let me know if I left out relevant information. 让我知道是否遗漏了相关信息。

Concerning your first problem: 关于第一个问题:

class Not should be public static, not public. class Not应该是public static,而不是public。

public class Test {

    static {

    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM