2009-11-10 6 views
2

Je souhaite copier le contenu d'un objet stocké dans une base de données vers un autre objet stocké dans une autre base de données. Je ne veux pas créer de fichier car j'ai plus de 300 Ko de fichiers à copier. Voici une partie de mon code:Copie du contenu documentum avec apache IOUtils.copy() et setContent()

ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

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

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

Si je ne pas accorder la machine virtuelle Java, IOUtils.copy(source.getContent(), baos); donne java.lang.OutOfMemoryError: Java heap space.

Si je règle la machine virtuelle Java en définissant la valeur Xmx max, l'instruction précédente est correcte, mais java.lang.OutOfMemoryError: Java heap space se produit avec targetObj.setContent(baos);.

Avec un seul 8332175 Bytes grand contenu ... (7,94 MB)

Toute idée de ce qui ne va pas? Une meilleure façon de copier depuis ByteArrayInputStream vers ByteArrayOutputStream? Autre chose?


Certaines API Documentum

getContent

publique ByteArrayInputStream getContent() lancers francs DfException

Des copies du contenu de cet objet à partir du serveur Documentum dans un ByteArrayInputStream> objet .

L'exemple de code suivant montre comment copier un contenu d'objets du> serveur Documentum en mémoire:

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

Renvoie: un objet contenant ByteArrayInputStream le contenu des objets. Lève: DfException - si une erreur de serveur se produit.

Et

setContent

setContent public boolean (contenu ByteArrayOutputStream) lancers francs DfException

Définit le nouveau contenu à un objet. Utilisez cette méthode lorsque vous souhaitez définir des données qui résident dans la mémoire de travail.

L'exemple de code suivant montre comment définir le contenu résidant dans la mémoire à un nouveau document:

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(); 

Paramètres: contenu - le contenu en tant que ByteArrayOutputStream. Lève: DfException - si une erreur de serveur se produit.

+0

Obtenez-vous le OutOfMemory de IOUtils ou de setContent()? – Thilo

+0

Où est-ce que vous faites exception. Et s'il vous plaît ajouter des liens à documentum api – jitter

+1

"Utilisez cette méthode lorsque vous souhaitez définir les données qui résident dans la mémoire de travail." Cela ressemble à un autre pour le cas où la date n'est pas dans la mémoire de travail ... – Thilo

Répondre

4

Tant que vous utilisez ByteArrayOutputStream, les données doivent être en mémoire.

Je ne connais rien à Documentum, mais y a-t-il un targetObj.setContent(File) ou un setContent(InputStream), de sorte que vous pouvez éviter de lire tout le morceau dans un byte[]?

(8MB est pas si énorme que, peut-être vous pouvez simplement ajuster l'espace de tas Java. Il pourrait également aider à pré-taille du tampon utilisé par le BAOS, vous pouvez passer la taille initiale à son constructeur)

Mise à jour: Etes-vous sûr que setContent prend un ByteArray Sortie Flux? Habituellement, un setter lirait à partir d'un InputStream.

+0

Il n'existe aucun autre moyen connu que setContent (BAOS) avec Documentum 5.3. Bien sûr, ma première action était d'augmenter le Xmx à 1024m, mais encore l'espace de tas java. Ce n'est pas une solution car je ne connais pas maxFileSize de la base de données. setContent (BAOS) et getContent() retourne un BAIS, c'est pourquoi j'utilise IOUtils.copy(); – enguerran

+0

bizarre. Vous avez un lien JavaDoc? – Thilo

+0

Si possible, éliminez tous les liens vers la source et son BAIS immédiatement après l'opération de copie, afin que sa copie des données puisse être récupérée. – Thilo

0

Si vous devez stocker ce temporairement dans la mémoire, puis augmenter la taille de votre mémoire JVM max en utilisant:

java -Xmx256m 

pour augmenter l'allocation de mémoire maximale de 256 Mo (valeur par défaut est 64 Mo). Voir here pour plus de détails.

+0

Malheureusement j'ai fixé -Xms1024m et -Xmx1024m ...encore OutOfMemoryError – enguerran

2

J'ai rencontré des problèmes de ce genre lorsque je traitais des fichiers volumineux et il n'y a pas de magie autre que d'essayer d'augmenter la taille de la pile. Je sais que vous avez dit que vous ne voulez pas créer un fichier localement sur le client où votre code est en cours d'exécution, mais vous voudrez peut-être jeter un oeil à faire cela avec les opérations. Essentiellement, vous devez simplement exécuter une opération d'exportation pour obtenir le fichier du référentiel source, puis utiliser une opération d'importation pour le créer dans la cible. Dans le cadre de l'opération d'importation, vous pouvez définir un indicateur pour supprimer le fichier source lorsque l'opération est terminée.

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

Vous avez raison, pas de solution magique: j'ai augmenté la taille du tas à 1640m (mon système max) et il semble être suffisant pour mes besoins (taille maximale du fichier: 8MB). J'ai essayé de créer un fichier temporaire local et c'était bien aussi. Donc pas de solution magique! ^^ – enguerran