将原始二进制数据与XML一起存储的最标准Java方法是什么? [英] What's the most standard Java way to store raw binary data along with XML?

查看:91
本文介绍了将原始二进制数据与XML一起存储的最标准Java方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将大量二进制数据存储到文件中,但我还想以XML格式读取/写入该文件的标题。

I need to store a huge amount of binary data into a file, but I want also to read/write the header of that file in XML format.

是的,我可以将二进制数据存储到某个XML值中,然后使用base64编码对其进行序列化。但这不会节省空间。

我可以以一种或多或少的标准方式混合XML数据和原始二进制数据吗?

Can I "mix" XML data and raw binary data in a more-or-less standardized way?

我在想两个选择:


  • 有没有使用JAXB执行此操作的方法?

  • Is there a way to do this using JAXB?

或者有没有办法获取一些现有的XML数据并将二进制数据附加到其中,以这种方式边界被识别了吗?

Or is there a way to take some existing XML data and append binary data to it, in such a way that the the boundary is recognized?

这不是我想要以某种方式用于/用于SOAP的概念吗?

Isn't the concept I'm looking for somehow used by / for SOAP?

或者是否在电子邮件标准中使用? (二元附件的分离)

Or is it used in the email standard? (Separation of binary attachments)

我想要实现的方案:

[meta-info-about-boundary][XML-data][boundary][raw-binary-data]

谢谢!

推荐答案

我遵循 Blaise Doughan 建议的概念,但没有附件marshallers:

I followed the concept suggested by Blaise Doughan, but without attachment marshallers:

我让 XmlAdapter byte [] 转换为 URI - 引用和返回,而引用指向存储原始数据的单独文件。然后将XML文件和所有二进制文件放入zip中。

I let an XmlAdapter convert a byte[] to a URI-reference and back, while references point to separate files, where raw data is stored. The XML file and all binary files are then put into a zip.

它类似于OpenOffice和ODF格式的方法,实际上是一个拉链很少XML和二进制文件。

It is similar to the approach of OpenOffice and the ODF format, which in fact is a zip with few XMLs and binary files.

(在示例代码中,没有写入实际的二进制文件,也没有创建zip。)

import java.net.*;
import java.util.*;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.*;

final class Bindings {

  static final String SCHEME = "storage";
  static final Class<?>[] ALL_CLASSES = new Class<?>[]{
    Root.class, RawRef.class
  };

  static final class RawRepository
      extends XmlAdapter<URI, byte[]> {

    final SortedMap<String, byte[]> map = new TreeMap<>();
    final String host;
    private int lastID = 0;

    RawRepository(String host) {
      this.host = host;
    }

    @Override
    public byte[] unmarshal(URI o) {
      if (!SCHEME.equals(o.getScheme())) {
        throw new Error("scheme is: " + o.getScheme()
            + ", while expected was: " + SCHEME);
      } else if (!host.equals(o.getHost())) {
        throw new Error("host is: " + o.getHost()
            + ", while expected was: " + host);
      }

      String key = o.getPath();
      if (!map.containsKey(key)) {
        throw new Error("key not found: " + key);
      }

      byte[] ret = map.get(key);
      return Arrays.copyOf(ret, ret.length);
    }

    @Override
    public URI marshal(byte[] o) {
      ++lastID;
      String key = String.valueOf(lastID);
      map.put(key, Arrays.copyOf(o, o.length));

      try {
        return new URI(SCHEME, host, "/" + key, null);
      } catch (URISyntaxException ex) {
        throw new Error(ex);
      }
    }

  }

  @XmlRootElement
  @XmlType
  static final class Root {

    @XmlElement
    final List<RawRef> element = new LinkedList<>();
  }

  @XmlType
  static final class RawRef {

    @XmlJavaTypeAdapter(RawRepository.class)
    @XmlElement
    byte[] raw = null;
  }

}



Main.java



Main.java

import java.io.*;
import javax.xml.bind.*;

public class _Run {

  public static void main(String[] args)
      throws Exception {
    JAXBContext context = JAXBContext.newInstance(Bindings.ALL_CLASSES);
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    Unmarshaller unmarshaller = context.createUnmarshaller();

    Bindings.RawRepository adapter = new Bindings.RawRepository("myZipVFS");
    marshaller.setAdapter(adapter);

    Bindings.RawRef ta1 = new Bindings.RawRef();
    ta1.raw = "THIS IS A STRING".getBytes();
    Bindings.RawRef ta2 = new Bindings.RawRef();
    ta2.raw = "THIS IS AN OTHER STRING".getBytes();

    Bindings.Root root = new Bindings.Root();
    root.element.add(ta1);
    root.element.add(ta2);

    StringWriter out = new StringWriter();
    marshaller.marshal(root, out);

    System.out.println(out.toString());
  }

}



输出



Output

<root>
    <element>
        <raw>storage://myZipVFS/1</raw>
    </element>
    <element>
        <raw>storage://myZipVFS/2</raw>
    </element>
</root>

这篇关于将原始二进制数据与XML一起存储的最标准Java方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆