Newsgroup: it.comp.java
Titolo: Errore copia file e risorse di sistema

Sto scrivendo un plugin per una applicazione (azureus), e la difficolta' 
principale sta nel fatto che non riesco a redirigere gli output delle 
eccezioni su un file esterno, quindi se qualcosa lancia un'eccezione posso 
solo visualizzarne il messaggio...
Il problema e': il plugin deve copiare dei file. Con file di piccole 
dimensioni (< 1mb) no problema, con file grandi (>300 mb) ritorna il 
messaggio "risorse di sistema insufficienti".
E' causato dal fatto che eseguo la copia dalla stessa applicazione del 
programma, e quindi vado ad occupare tutta la memoria assegnatagli 
precedentemente? Ma questa non si incrementa da sola?Come posso 
risolvere?ah, la ram ovviamente non è del tutto piena, ci sono almeno 200 mb 
liberi....
-- 
"Avro' qualche problema con lei, signor Bond?"
"No, lei non e' il mio tipo"
"Brillante?"
"No, single" 

 precedentemente? Ma questa non si incrementa da sola?Come posso 
si incrementa fino ad un certo punto. il massimo specificato.


Eccolo qua.....
public static void copyFile(File sourceFile, File destFile) throws 
IOException {
  if(destFile.isDirectory())
   destFile = new File(destFile.getAbsolutePath() + "/" + 
sourceFile.getName());
   if(!destFile.exists()) {
    destFile.createNewFile();
   }
   FileChannel source = null;
   FileChannel destination = null;
   try {
    source = new FileInputStream(sourceFile).getChannel();
    destination = new FileOutputStream(destFile).getChannel();
    destination.transferFrom(source, 0, source.size());
   }
   finally {
    if(source != null) {
     source.close();
    }
    if(destination != null) {
     destination.close();
    }
  }
 } 

    {
Comunque la sto provando adesso....
Grazie mille per la rapidita' e l'aiuto, comunque! :) 

     destination.transferFrom(source, 0, source.size());
leggi la javadoc e capirai che tenta di leggere source.size() byte e *poi*
li scrive
leggi: bum
leggila anche perche' potrebbe leggere meno dei byte che gli chiedi e
quindi rendere abbastanza inutile il tuo codice.
leggi: devi fare un ciclo controllando il valore di ritorno
in sinstesi leggi sempre la javadoc.... l'ideale sarebbe prima di
causare guai ma se qualcosa non va e' d'obbligo almeno dopo

 causare guai ma se qualcosa non va e' d'obbligo almeno dopo
Credo tra l'altro che sia un bug di java...
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4938442
Ok, trovero' qualcosa... 


Fatto, ho messo i cicli di controllo...il problema è che filechannel alloca 
veramente troppa ram (circa l'80% della dimensione del file da copiare, 
ovviamente dipende da dove si copia e la sua dimensione) ed inoltre ha una 
specie di bug con il trasferimaneto di grossi file verso cartelle 
remote...ho risolto con la copia byte per byte, ma ci vuole veramente una 
vita, un'altra soluzione alla quale ho pensato è sfruttare le chiamate a 
runtime, che sono sicuramente più efficienti di qualsiasi classe ma perdo 
sia la portabilità (poco importa, tanto non cambio sistema operativo ogni 
15gg) ma soprattuto non ho controllo di quello che succede, quindi non so se 
e' effettivamente partita la copia (magari un nome era errato), se si e' 
conclusa a buon fine, quanto ci ha messo.....uffi.....un aiutino? 

> buon fine, quanto ci ha messo.....uffi.....un aiutino?
Ok, sono stanco...ho risolto cambiando
source.transferTo(0, source.size(), destination);
con
int maxCount = 32 * 1024 * 1024;
         long size = source.size();
         long position = 0;
         while (position < size) {
             position += source.transferTo(position, maxCount,destination);
         }
ora impiega 2m30s per un file da 400MB via lan...quasi normale... 

 ora impiega 2m30s per un file da 400MB via lan...quasi normale...
usa i Buffered*Stream



e ricordati di fare un flush prima della chiusura del
BufferedOutputStream