【问题标题】:Get progress information during JAXB de-/serialization在 JAXB 反序列化/序列化期间获取进度信息
【发布时间】:2017-08-14 11:16:07
【问题描述】:

有没有办法在 JAXB Marshaller 和 Unmarshaller 上注册一些进度监视器? 我想在数据反序列化/序列化时在我的 GUI 中显示一些进度信息。

我看到你可以设置一个Unmarshaller.ListenerMarshaller.Listener,它们有一个“之前”和“之后”的方法。不过,我没有看到任何直接的方法来获取要序列化的元素总数。

我显然需要它来计算一些“完成百分比”信息。

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    解组前解析可以吗?

    如果是这样,假设您有一个对象列表,您可以执行类似...

        final String tagName = *** name of tag you are counting ***;
        InputStream in = *** stream of your xml ***;
    
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser saxParser = spf.newSAXParser();
        final AtomicInteger counter = new AtomicInteger();
        saxParser.parse(in, new DefaultHandler() {
            @Override
            public void startElement (String uri, String localName, String qName, Attributes attributes) {
                if (localName.equals(tagName))
                    counter.incrementAndGet();
            }
        });
    

    【讨论】:

    • 这可能是一种解决方法。我的 tagName 在 xml 树中不是唯一的怎么办?
    • 然后检查一组名称而不是单个名称。
    • 编组是否类似?
    【解决方案2】:

    通过利用 InputStream 来做一个更底层的方法是一个可接受的解决方案吗?

    例如

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.function.DoubleConsumer;
    
    public class InputStreamWithProgressDecorator extends InputStream {
        /** Input stream to be decorated */ private final InputStream inputStream;
        /** Amount of byte read */ private long position = 0L;
        /** File size */ private final long length;
        /** Mark */ private int mark = 0;
        /** Consumer of the progress */ private final DoubleConsumer callBack;
        
        public InputStreamWithProgressDecorator(final InputStream is, final long l, final DoubleConsumer cb) {
            inputStream = is;
            length = l;
            callBack = cb;
        }
    
        private void setPosition(final long fp) {
            position = fp;
            callBack.accept(getProgress());
        }
    
        public double getProgress() {
            return length == 0L ? 100d : ((double) position) * 100d / ((double) length);
        }
    
        public long getPosition() {
            return position;
        }
    
        @Override
        public int read(byte[] b) throws IOException {
            final int rc = inputStream.read(b);
            setPosition(position + rc);
            return rc;
        }
    
        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            final int rc = inputStream.read(b, off, len);
            setPosition(position + rc);
            return rc;
        }
    
        @Override
        public byte[] readAllBytes() throws IOException {
            final byte[] result = inputStream.readAllBytes();
            setPosition(position + result.length);
            return result;
        }
    
        @Override
        public byte[] readNBytes(int len) throws IOException {
            final byte[] result = inputStream.readNBytes(len);
            setPosition(position + result.length);
            return result;
        }
    
        @Override
        public int readNBytes(byte[] b, int off, int len) throws IOException {
            final int rc = inputStream.readNBytes(b, off, len);
            setPosition(position + rc);
            return rc;
        }
    
        @Override
        public long skip(long n) throws IOException {
            final long rc = inputStream.skip(n);
            setPosition(position + rc);
            return rc;
        }
    
        @Override
        public int available() throws IOException {
            return inputStream.available();
        }
    
        @Override
        public void close() throws IOException {
            inputStream.close();
        }
    
        @Override
        public synchronized void mark(int readlimit) {
            inputStream.mark(readlimit);
            mark = readlimit;
        }
    
        @Override
        public synchronized void reset() throws IOException {
            inputStream.reset();
            setPosition(mark);
        }
    
        @Override
        public boolean markSupported() {
            return inputStream.markSupported();
        }
    
        @Override
        public int read() throws IOException {
            final int c = inputStream.read();
            setPosition(position + 1);
            return c;
        }
    }
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.function.DoubleConsumer;
    
    public class Demo1 {
    
        public static void main(String[] args) throws IOException {
            final File file = new File(args[0]);
            final DoubleConsumer callBack = p -> System.out.printf("%.0f%%\n", p);
            try (final FileInputStream fis = new FileInputStream(file); final InputStreamWithProgressDecorator is = new InputStreamWithProgressDecorator(fis, file.length(), callBack)) {
                // Simulating JAXB unmarshaller reads
                byte[] buffer = is.readNBytes(1024);
                while (buffer.length != 0) buffer = is.readNBytes(1024); 
            }
        }
    }
    

    或者,如果您有一个带有单独线程方法的 FileInputStream:

    public class FileInputStreamReadProgressThread extends Thread implements UncaughtExceptionHandler {
        /** Input stream */ private final FileInputStream fileInputStream;
        /** File size */ private final long length;
        /** Read progress in percents */ private double progress = 0d;
        /** Exception from thread */ private Throwable exception = null;
        /** Consumer of the progress */ private final DoubleConsumer callBack;
    
        public FileInputStreamReadProgressThread(final FileInputStream fis, final long l, final DoubleConsumer cb) {
            fileInputStream = fis;
            length = l;
            callBack = cb;
            setUncaughtExceptionHandler(this);
            setName(getClass().getSimpleName());
        }
    
        public double getProgress() { return progress; }
        public Throwable getException() { return exception; }
        @Override public void uncaughtException(final Thread t, final Throwable e) { exception = e; }
        
        @Override
        public void run() {
            try {
                long position = -1L;
                final FileChannel channel = fileInputStream.getChannel();
                while (!isInterrupted() && channel.isOpen() && position < length) {
                    position = channel.position();
                    progress = length == 0L ? 100d : ((double)position) * 100d / ((double)length);
                    callBack.accept(progress);
                    sleep(100L);
                } 
            } catch (final IOException e) {
                exception = e;
            } catch (final InterruptedException e) {
                // Do nothing
            }
        }
    }
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.nio.channels.Channels;
    import java.util.function.DoubleConsumer;
    
    public class Demo2 {
    
        public static void main(String[] args) throws IOException {
            final File file = new File(args[0]);
            final DoubleConsumer callBack = p -> System.out.printf("%.0f%%\n", p);
            try (final FileInputStream fis = new FileInputStream(file); final InputStream is = Channels.newInputStream(fis.getChannel())) {
                final FileInputStreamReadProgressThread readProgressThread = new FileInputStreamReadProgressThread(fis, file.length(), callBack);
                readProgressThread.start();
                // Simulating JAXB unmarshaller reads
                is.readAllBytes();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多