使用apache IOUtils.copy()和setContent()复制documentum内容

时间:2009-11-10 10:05:57

标签: java copy apache-commons documentum

我想将内容从一个docbase中存储的一个对象复制到另一个docbase中存储的另一个对象。我不想创建文件,因为我要复制超过300个k文件。以下是我的代码的一部分:

ByteArrayOutputStream baos = new ByteArrayOutputStream();

IOUtils.copy(source.getContent(), baos);

[...]
targetObj.setContent(baos); // Documentum DFC
targetObj.save(); // Documentum DFC

如果我不调整 JVM,IOUtils.copy(source.getContent(), baos);java.lang.OutOfMemoryError: Java heap space

如果我通过设置Xmx max值来调整JVM,则前一条指令没问题,但java.lang.OutOfMemoryError: Java heap spacetargetObj.setContent(baos);一起发生。

只有8332175字节大内容......(7.94 MB)

知道什么是错的吗?从ByteArrayInputStream复制到ByteArrayOutputStream的更好方法是什么?还有别的吗?


某些Documentum API

  

的getContent

     

public ByteArrayInputStream getContent()                                  抛出DfException

     

将此对象的内容从Documentum服务器复制到ByteArrayInputStream>对象中。

     

以下代码示例演示了如何将对象内容从> Documentum服务器复制到内存中:

    IDfSysObject sysObj = (IDfSysObject)session.getObject(new DfId("0900d5bb8001f900"));
    ByteArrayInputStream bais = sysObj.getContent();
    if (bais.available() > 0)
    {
         // Data successfully fetched from the server...
    }
     

返回:          包含对象内容的ByteArrayInputStream对象。      抛出:          DfException - 如果发生服务器错误。

  

setContent

     

public boolean setContent(ByteArrayOutputStream content)                     抛出DfException

     

为对象设置新内容。如果要设置驻留在工作内存中的数据,请使用此方法。

     

以下代码示例演示如何将驻留在内存中的内容设置为新文档:

    IDfSysObject sysObj = (IDfSysObject)sess.newObject("dm_document");
    sysObj.setObjectName("testDoc");
    sysObj.setContentType("crtext");
    byte b[] = {35,36,37,38,39};
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.write(b, 0, 5);
    sysObj.setContent(out);
    sysObj.save();
     

参数:          content - 作为ByteArrayOutputStream的内容。      抛出:          DfException - 如果发生服务器错误。

3 个答案:

答案 0 :(得分:4)

只要您使用ByteArrayOutputStream,数据就必须适合内存。

我对Documentum一无所知,但可能有targetObj.setContent(File)setContent(InputStream),这样您就可以避免将整个块读入byte[]

(8MB并不是那么大,也许你可以调整Java堆空间。它也可以帮助预先调整BAOS使用的缓冲区大小,你可以将初始大小传递给它的构造函数)

更新:您确定setContent采用ByteArray 输出流吗?通常,setter会从InputStream中读取。

答案 1 :(得分:2)

在处理大型文件时遇到了类似的问题,除了尝试增加堆大小之外,它确实没有任何魔力。我知道你说你不想在运行代码的客户端上本地创建一个文件,但是你可能想看一下这个操作。基本上,您只需运行导出操作以从源存储库获取文件,然后使用导入操作在目标中创建它。作为导入操作的一部分,您可以设置一个标志,以便在操作完成时删除源文件。

   IDfClientEx clientx = new DfClientEx();
   IDfExportOperation exOp = clientx.getExportOperation();
   IDfSysObject exportObj = getObjectToExport();
   IDfExportNode = (IDfExportNode) exOp.add(exportObj);
   exOp.execute();
   String path = exOp.getFilePath();

   IDfImportOperation impOper = clientx.getImportOperation();
   IDfFile dfFile = new DfFile(path);
   IDfImportNode impNode = (IDfImportNode) impOper.add(dfFile);
   impNode.setDocbaseObjectType("dm_document");
   impNode.setDestinationFolderId(importFolderId);
   impNode.setNewObjectName("testDoc");
   impNode.setFormat("crtext");
   impOper.setKeepLocalFile(false);
   impOper.execute();

答案 2 :(得分:0)

如果您需要暂时将其存储在内存中,请使用以下命令增加JVM最大内存大小:

java -Xmx256m

将最大内存分配增加到256Mb(默认为64Mb)。有关详细信息,请参阅here