Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [JAVA] Scrittura e lettura a blocchi file

    Ciao ragazzi,
    sto sviluppando una applicazione client-server in cui è necessario trasferire dei files. Sto usando degli stream di comunicazione, associati al socket, del tipo ObjectInputStream e ObjectOutputStream. Per il trasferimento di dati di grosse dimensioni (tipo 100,200 MB, o anche oltre),che dovrebbe performare anche inn rete, come posso fare? Non mi è molto chiaro come funziona la scrittura a blocchi. Qualcuno potrebbe scrivere il codice di scrittura/lettura a blocchi del file (o sugli stream del socket se necessario)? Grazie mille, ragazzi

  2. #2

    [JAVA] Scrittura e lettura a blocchi file

    In pratica ho risolto aumentando la memoria heap della java virtual machine. Faccio la lettura del file, lo trasformo in un byte[] (questo passaggio mi saturava la memoria heap), e lo invio blocco per blocco tramite socket. Ci sono metodi più efficienti o più rapidi, che voi sappiate?
    Per leggere un file di 200 mega, mi serve 1.5Gb di memoria heap, all'incirca :|

  3. #3
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,319
    Una "miglioria" è sicuramente quella di non usare ObjectInputStream e ObjectOutputStream, se non sono strettamente richiesti dal protocollo, che effettuano, per nulla, una serializzazione dell'oggetto. Se devi semplicemente trasferire dei byte, usa direttamente i semplici InputStream/OutputStream della socket... al massimo wrappali su degli stream bufferizzati.

    Altra "miglioria": perchè leggere prima tutto il file per poi inviarlo? Invialo man mano che lo leggi, così non hai bisogno di tutta quella memoria...

    Altra soluzione che dovrebbe migliorare le prestazioni è usare java.nio con i SocketChannel e FileChannel.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  4. #4

    [JAVA] Scrittura e lettura a blocchi file

    Innanzitutto grazie mille, Lele.
    Riguardo la lettura del file "poco alla volta"(a blocchi) che citi nel tuo commento, potresti farmi vedere un attimo come farla? Era proprio quello che volevo fare. Io leggo il file così:

    codice:
    FileInputStream fileIn = new FileInputStream(fileName);		
    			long fileLen =  (new File(fileName)).length();		 
    			int intFileLen = (int)fileLen;		 
    			byte[] byteArray = new byte[intFileLen];
    			fileIn.read(byteArray);
    			fileIn.close();
    
    /* invio l'array di byte byteArray, un elemento per volta, utilizzando il socket su cui comunicano client e server, usando un ciclo for*/
    Ovviamente la creazione di un byteArray, quando ho un file grosso, grande quanto il file stesso mi "costa" parecchia memoria.
    Purtroppo, uso gli ObjectInputStream o ObjectOutputSTream, perché nel corso della comunicazione invio oggetti che serializzo e riutilizzo a destinazione e mi sembrano comodi a tale scopo.

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,319
    Grossomodo, quello che andrebbe fatto è questo:

    codice:
    // Creo l'InputStream per leggere dal file
    FileInputStream fis = new FileInputStream( fileName );
    
    // Ottengo l'OutputStream per scrivere sulla socket e lo wrappo
    // in un BufferedOutputStream per ottenere uno stream bufferizzato
    BufferedOutputStream bos = new BufferedOutputStream( socket.getOutputStream() );
    
    // Strutture dati per la lettura/scrittura dei byte
    
    // 32 KB di dati per blocco
    byte[] dati = new byte[32 * 1024];
    
    // Numero di byte letti dal file
    int byteLetti = 0;
    
    // Ora leggo un blocco alla volta...
    while((byteLetti = fis.read(dati)) >= 0) {
    
       // ... e lo scrivo sulla socket immediatamente
       bos.write(dati, 0, byteLetti);
    
       // non indispensabile, ma utile: pulisco il buffer di lettura
       Arrays.fill(dati, (byte) 0);
    }
    
    // Ho finito di leggere e spedire il file... effettuo un flush per
    // svuotare il buffer di scrittura
    bos.flush();
    
    // Chiudo il file
    fis.close();
    Attenzione che non ho effettuato alcuna gestione delle eccezioni, intendendo questo come un codice puramente dimostrativo del funzionamento. In ambito reale è necessario effettuare una corretta gestione delle eccezioni e avvalersi del blocco finally per la chiusura degli stream.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6

    [JAVA] Scrittura e lettura a blocchi file

    LeleFT, ti ringrazio tantissimo per la tua disponibilità e per l'efficacia del tuo aiuto. Ho risolto quanto ti chiedevo, gestendo la lettura con gli opportuni blocchi try - catch. Non è necessario sparare a mille la memoria heap della JVM con tale modo di procedere. Ora funziona tutto. Grazie mille ancora e alla prossima

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.