如何将 EMF 对象持久化到 OutputStream?

How to persist EMF objects to OutputStream?

这就是我如何将两个 EMF 对象(静态 shelf 和动态 md5)保存到压缩二进制文件中的方法:

static void save(Shelf shelf, String file, EClass md5class) throws Exception { 
  EObject md5 = stringToMD5EObject("0x0abc", md5class); 
  Resource resource = createResource(file, md5class.getEPackage(), shelf.eClass().getEPackage());
  resource.getContents().add(md5); 
  resource.getContents().add(shelf); 
  resource.save(options());
}
static Resource createResource(String file, EPackage... packages) {
  ResourceSet resourceSet = new ResourceSetImpl();
  Resource.Factory factory = uri -> new BinaryResourceImpl(uri);
  resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("bin", factory); 
  for (EPackage p : packages) resourceSet.getPackageRegistry().put(p.getNsURI(), p);
  URI fileURI = URI.createFileURI(new File(file).getAbsolutePath());
  return resourceSet.createResource(fileURI);
}
static Map<String, Object> options() {
  return Collections.singletonMap(BinaryResourceImpl.OPTION_ZIP, Boolean.TRUE);
}

问题是如果我得到一个已经打开 OutputStream,即无法访问文件名,如何配置资源?

这里有一个解决方案供以后参考:

static {
    options = Collections.singletonMap(BinaryResourceImpl.OPTION_ZIP, true);
}

public void save(OutputStream outputStream, EObject ... eObject) throws Exception {
    Resource resource = createResource(Arrays.stream(eObject).map(x -> x.eClass().getEPackage()));
    Arrays.stream(eObject).forEach(resource.getContents()::add);
    resource.save(outputStream, options);
}

public EList<EObject> load(InputStream inputStream, EPackage ... packages) throws Exception {
    Resource resource = createResource(Arrays.stream(packages));
    resource.load(inputStream, options);
    return resource.getContents();
}
    
private Resource createResource(Stream<EPackage> packages) {
    ResourceSet resourceSet = new ResourceSetImpl();
    Resource.Factory resourceFactory = __ -> new BinaryResourceImpl();
    resourceSet.getResourceFactoryRegistry().getContentTypeToFactoryMap().put("*", resourceFactory);
    packages.forEach(p -> resourceSet.getPackageRegistry().put(p.getNsURI(), p));
    return resourceSet.createResource(null);
}