Скопируйте содержимое документа с помощью apache IOUtils.copy () и setContent () - PullRequest
3 голосов
/ 10 ноября 2009

Я хочу скопировать содержимое из одного объекта, хранящегося в одной базе документов, в другой объект, хранящийся в другой базе документов. Я не хочу создавать файл, потому что у меня есть более 300 тысяч файлов для копирования. Ниже часть моего кода:

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.

Если я настрою JVM, установив максимальное значение Xmx, предыдущая инструкция в порядке, но java.lang.OutOfMemoryError: Java heap space происходит с targetObj.setContent(baos);.

С большим содержимым всего 8332175 байт ... (7,94 МБ)

Есть идеи, что случилось? Лучший способ скопировать из ByteArrayInputStream в ByteArrayOutputStream? Что-то еще?


Некоторые API Documentum

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) выдает 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 ]

4 голосов
/ 10 ноября 2009

Пока вы используете ByteArrayOutputStream, данные должны помещаться в памяти.

Я ничего не знаю о Documentum, но, может быть, есть targetObj.setContent(File) или setContent(InputStream), так что вы можете избежать чтения всего фрагмента в byte[]?

(8МБ не так уж и велик, хотя, может быть, вы можете просто настроить пространство кучи Java. Это также может помочь предварительно настроить размер буфера, используемого BAOS, вы можете передать начальный размер его конструктору)

Обновление: Вы уверены, что setContent принимает ByteArray Выход Поток? Обычно сеттер читает из InputStream.

2 голосов
/ 13 ноября 2009

Я сталкивался с подобными проблемами при работе с большими файлами, и на самом деле в этом нет никакой магии, кроме попытки увеличить размер кучи. Я знаю, что вы сказали, что не хотите создавать файл локально на клиенте, где работает ваш код, но вы можете взглянуть на это с помощью операций. По сути, вы просто запустите операцию экспорта, чтобы получить файл из исходного репозитория, а затем используйте операцию импорта, чтобы создать его в целевом объекте. В рамках операции импорта есть флаг, который можно установить для удаления исходного файла после завершения операции.

   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();
0 голосов
/ 10 ноября 2009

Если вам нужно временно сохранить это в памяти, увеличьте максимальный объем памяти JVM с помощью:

java -Xmx256m

, чтобы увеличить максимальное выделение памяти до 256 МБ (по умолчанию 64 МБ). Подробнее см. здесь .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...