3

あるドックベースに格納されているあるオブジェクトのコンテンツを、別のドックベースに格納されている別のオブジェクトにコピーしたいと考えています。コピーするファイルが 30 万を超えるため、ファイルを作成したくありません。以下は私のコードの一部です:

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 spaceが、targetObj.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 - サーバー エラーが発生した場合。

4

3 に答える 3

4

を使用している限りByteArrayOutputStream、データはメモリに収まる必要があります。

Documentum については何も知りませんが、targetObj.setContent(File)チャンクsetContent(InputStream)全体をbyte[].

(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 に答える