Newsgroup: it.comp.java
Titolo: append file in modalita' esclusiva

In una rete locale ci sono piu' applicazioni Java che scrivono delle linee di
testo su di un file posto in una directory condivisa.
Le applicazioni utilizzano la seguente funzione per appendere le linee al file
    static void AppendFile (String nomeFile, String s) {
        try {
            DataOutputStream d = new DataOutputStream
                                (new FileOutputStream (nomeFile, true));
            d.writeBytes(s);
            d.flush();
        } catch (IOException e) {
            System.out.println("Non posso aprire il file <" + nomeFile + ">");
        }
    }  // end AppendFile
Come posso fare per impedire che piu' applicazioni scrivano contemporaneamente
sul file mischiando le linee contenute nel parametro String s  ?
Ciao
---------------------------------------
Email: sostituire "nospam" con "uol"

 sul file mischiando le linee contenute nel parametro String s  ?
Potresti dichiarare synchronized il metodo cosi' ci puo' essere un
singolo
accesso alla volta.
Se la scrittura sul file puo' avvenire solo attraverso quel
metodo, che per di piu' e' statico, non dovresti avere problemi
dichiarandolo synchronized.
Ciao,
  Marina



Dipende - cio' che suggerisci e' vero solo se le applicazioni lavorano
nello stesso spazio di indirizzamento - girano nella stessa JVM in
altre parole. Se sono in JVM diverse invece, come mi pare di indurre
dalla domanda (...in rete locale...) avrai un'istanza della classe per
ogni applicazione e la sincronizzazione non esiste.
Comunque cosi' il problema e' piu' interssante :) - e gli approcci
possibili sono diversi. Traslasciando le soluzioni a livello di s/o e
quelle a livello filesystem, generalmente brutte e poco efficaci,
quello piu' semplice e' creare un processo sempre attivo su una
macchina server - a cui vengano delegate le *effettive* scritture sul
file. Le applicazioni (attraverso istanze diverse della classe che
esegue la scrittura) comunicano a questo processo le loro richieste di
scrittura. Il processo le accoda e le esegue nell'ordine voluto.
Ovviamente le applicazioni non devono *piu'* "vedere" direttamente il
file.
Una soluzione del genere puo' essere implementata, indifferentemente,
con le normali socket BSD o con un ORB corba o invocando il metodo di
scrittura via RMI (in tal caso ci sarebbe effettivamente una sola
istanza della classe che scrive, e tanti proxy visti dalle varie
applicazioni. Qui il synchronized di Marina torna utile.)
Questa e' l'idea generale. Per i dettagli.. buon divertimento! :)
Saluti,
	Cris

 dichiarandolo synchronized.
Da quello che ho capito potrebbero essere applicazioni diverse su
macchine (fisiche o virtuali) diverse.
Credo sia possibile agire in due modi:
1 - un istanza comune della classe che gestisce l'accesso al file con
chiamate remote delle applicazioni, in questo caso il syncronized ha
senso
2 - un sistema di "lock" implementato a parte, visto che java non
consente di fatto il lock dei file. Es, un file temporaneo che fa da
"semaforo".
Tecnologicamente la 1 č meglio.

applicazioni. Qui il synchronized di Marina torna utile.)
Della tecnica RMI ne ho solo sentito parlare


 utilizzare un file ausiliario come semaforo  :-(
Per il file locking esistono solo soluzioni "native". Inoltre non tutti
i file system lo supportano in modo sicuro. 
L'uso di semafori è sicuramente l'unica soluzione portabile al 100%. Il
difetto è evidente, non hai nessun aiuto da parte del sistema operativo
e del file system. E' un sistema di locking che gestisci tu al 100% da
applicativo, quindi devi essere "bravo" da gestirlo come si deve.
Inoltre nonostante esista (in java2) nella classe File il metodo
deleteOnExit() (o simile, ora non ricordo) che consente di cancellare
comunque il file-semaforo quando termina la JVM, se la JVM termina in
modo anomalo potrebbe rimanere un "lock" vagante.

Della tecnica RMI ne ho solo sentito parlare
RMI (remiote method invocation) ti permette di far parlare (invocare
metodi, cioe') oggetti che girano su macchine virtuali diverse -
proprio quel che ti serve!!  Nella documentazione di JDK trovi i
dettagli.