Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479

    Trasferimento file grandi dimensioni

    Ciao a tutti!!!
    sto realizzando un programma per il file sharing e appunto ho la necessita di eseguire dei download/upload. Finche' il file e' di piccole dimensioni ( per ora ho provato file da 3 mb circa ) tutto funziona senza problemi, ma quando trasferisco file molto grossi ( 300 MB ) mi viene sollevata una OutOfMemoryError. Ho provato ad aumentare la memoria della jvm fino a 128 mb ma niente, il file viene trasferito un po' di piu ma alla fine si blocca ugualmente.Per il momento ho provato solo in locale e non tra 2 PC separati quindi non so se si genera lo stesso errore. Comunque in generale, come potrei risolvere questo problema? Trasferisco blocchi di 4kb alla volta.
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  2. #2
    Utente di HTML.it
    Registrato dal
    Aug 2002
    Messaggi
    8,013
    Bisognerebbe vedere un po' di codice (come leggi il file e come lo invii). A "naso" direi che sarebbe il caso di utilizzare, se non lo stai già facendo, un RandomAccessFile
    <´¯)(¯`¤._)(¯`»ANDREA«´¯)(_.¤´¯)(¯`>
    "The answer to your question is: welcome to tomorrow"

  3. #3
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Ecco il codice:

    Uploader:
    codice:
    File file = new File(percorsoFile);
    FileInputStream fis = new FileInputStream(file);
    			
    byte[] dati = new byte[DIMENSIONE];	
    int quanti;
    
    while((quanti = fis.read (dati)) > 0)
    {
        out.writeObject (new MessaggioDati( dati,
        		                            quanti) );	
        dati = new byte[DIMENSIONE];
    }
    
    in.close();
    out.close();
    Downloader:

    codice:
    File file = new File(nomeFile );
    			
    FileOutputStream fos = new FileOutputStream( file );
    
    MessaggioDati messaggioDati;
    			
    while( (messaggioDati = (MessaggioDati) in.readObject()).quanti() > 0 )
    {
    	fos.write( messaggioDati.dati(), 0, messaggioDati.quanti() );
    	fos.flush();
    }
    ho provato a cambiarlo con RandomAccessFile ma stesso risultato, arrivo a trasferire 62 MB. Ora c'e' da dire che sto facendo girare 2 istanze del programma sulla stessa macchina, di sicuro se lo faccio girare su 2 pc diversi le cose potrebbero cambiare...adesso provo.
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Hai usato la serializzazione. E c'è una questione di fondo che probabilmente non sai.
    Durante l'utilizzo di un ObjectOutputStream, gli oggetti scritti vengono "cachati", referenziati e mantenuti in vita all'interno del ObjectOutputStream. Questo perché ObjectOutputStream se vede un oggetto che ha già scritto in precedenza, in realtà scrive solo un "riferimento" all'oggetto.

    Nel tuo caso crei tanti nuovi oggetti MessaggioDati e ognuno ha pure un array nuovo di zecca. Quindi fa molto in fretta ad occupare tutta la memoria!
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Ah...non lo sapevo questo.
    Quindi come potrei risolvere il problema?
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  6. #6
    Utente di HTML.it L'avatar di Poker1
    Registrato dal
    Jul 2002
    Messaggi
    479
    Forse sono riuscito a risolvere il problema, ho fatto cosi:

    codice:
    File file = new File(percorsoFile);
    FileInputStream fis = new FileInputStream(file);
    			
    byte[] dati = new byte[DIMENSIONE];	
    int quanti;
    
    while((quanti = fis.read (dati)) > 0)
    {
        out.writeObject (new MessaggioDati( dati,
        		                            quanti) );	
        dati = new byte[DIMENSIONE];
        out.reset();
    }
    
    in.close();
    out.close();
    Praticamente avendo aggiungo la out.reset(); e' come se creassi un nuovo ObjectOutputStream ogni volta giusto? In questo modo il Garbage Collector quando partira' vedra' tutti questi oggetti non riferiti e li toglie.

    Ho provato a trasferire il file da 320 MB ( usando 2 pc ) e tutto e' andato a buon fine, sara' stato un caso... ?
    Non riscrivere la ruota, usa le librerie.
    by Bjarne Stroustrup
    EIDON SOFT MEMBER

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Poker1
    codice:
    out.reset();
    Praticamente avendo aggiungo la out.reset(); e' come se creassi un nuovo ObjectOutputStream ogni volta giusto?
    reset() fa sostanzialmente 2 cose: scrive sullo stream 1 byte di marcatura che indica il reset e poi svuota le sue strutture dati che tengono in cache gli oggetti. Se non ci sono più altri riferimenti a quei oggetti, diventano eleggibili per il g.c.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.