3

我想将内容从存储在一个文档库中的一个对象复制到存储在另一个文档库中的另一个对象。我不想创建文件,因为我有超过 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 最大值来调整 JVM,那么前面的指令是可以的,但是java.lang.OutOfMemoryError: Java heap space会出现targetObj.setContent(baos);.

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

知道有什么问题吗?从 ByteArrayInputStream 复制到 ByteArrayOutputStream 的更好方法?还有什么?


一些 Documentum API

获取内容

公共 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(ByteArrayOutputStream 内容)抛出 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 - 如果发生服务器错误。

4

3 回答 3

4

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

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

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

更新:你确定 setContent 需要一个 ByteArray输出流吗?通常,setter 会从 InputStream 中读取。

于 2009-11-10T10:14:12.363 回答
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();
于 2009-11-13T20:38:03.750 回答
0

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

java -Xmx256m

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

于 2009-11-10T10:23:24.230 回答