View Full Version : [JAVA7]un Virtual File con... ?


Frank1962
18-08-2009, 15:39
Un pò per necessità e un pò per sfizio (e anche perchè forse il caldo mi ha dato alla testa) ho avuto l'idea di voler creare un programma in JAVA che mi crei "dinamicamente" una Virtual Directory/File nel sistema ...che cosa intendo per virtuale? ...intendo che il file e/o dir creata risulta essere presente nel file system come una cartella e/o file reale ma che a ogni lettura o scrittura venga in realtà gestito da questo programma e che il contenuto venga generato da questo nella fase di lettura da un programma x.
Detto questo sento già la lapidaria risposta --> JNI!! ...però spulciando quà e là tra il framework offerto dalle nuove NIO2 del Java 7 ho visto che sono presenti delle interessanti classi con ancor più interessanti funzionalità (o forse sono io che ho sopravvalutato quello scritto nel doc) ...le classi in questione sono queste:


AsynchronousFileChannel (http://www.openjdk.org/projects/nio/javadoc/java/nio/channels/AsynchronousFileChannel.html)
SeekableByteChannel (http://www.openjdk.org/projects/nio/javadoc/java/nio/channels/SeekableByteChannel.html)
SecureDirectoryStream (http://www.openjdk.org/projects/nio/javadoc/java/nio/file/SecureDirectoryStream.html)

La ultima in questione ha nella documentazione proprio la dicitura: A SecureDirectoryStream may also be used as a virtual working directory.
Questa frase può dire tutto o nulla ....cosa intendono gli sviluppatori della NIO2 per "virtual working directory"? ...e se fosse quello che serve a me come posso usare un "SeekableByteChannel" per "catturare" le letture e scritture dei dati?

Per l'AsynchronousFileChannel sono un pò perplesso perchè penso che "l'asincrono" riguarda il programma Java in se e non il fatto che la creazione di questo canale in realtà sia un modo per "attendere" la richiesta di lettura o scrittura da parte di un'altro programma.

Detto questo mi appello a qualcuno che forse ha le idee più chiare su queste nuove librerie (NIO2) perchè mi sa che probabilmente mi toccherà ravanare un pò con JNI e C#! :muro:

Frank1962
18-08-2009, 23:59
possibile che nessuno si sia interssato alle nuove NIO2 del Java 7!!? ...e non intendo solo quà nel forum ...anche in giro per la internet mondiale ci sono pochissime pagine che parlano, e anche molto sommariamente, di queste classi :cry:

PGI-Bis
19-08-2009, 12:52
Su OpenJDK trovi le slide di JavaOne

http://openjdk.java.net/projects/nio/presentations/TS-5686.pdf
http://openjdk.java.net/projects/nio/presentations/TS-5052.pdf
http://openjdk.java.net/projects/nio/presentations/TS-4222.pdf

Allo stato attuale comunque l'unica via è provare

https://jdk7.dev.java.net/

PGI-Bis
19-08-2009, 12:57
Ah, anche la javadoc è un buon punto d'inizio

http://download.java.net/jdk7/docs/api/index.html

Frank1962
19-08-2009, 19:23
si si PGI i doc della Java 7 li ho letti e come (almeno per le classi/librerie che ho indicato) ma non ho trovato un granghè di spiegazione; anche nelle presentazioni che mi hai indicato e che avevo già letto a suo tempo o trovato poco o nulla che possa aiutarmi a trovare una soluzione, per esempio, per la classe SecureDirectoryStream non c'è nessun approfondimento che spieghi il suo utilizzo ....sembra quasi che pure gli alutori della stessa classe siano in dubbio di quale funzionalità debba/non debba avere: infatti in un post del 2005 ho letto che uno degli autori della NIO2 diceva che questa nuova libreria NON supportava la possibilità di creare un Virtual File System ....mentre adesso nella spiegazione della classe SecureDirectoryStream viene indicata la possibilità di fare ciò (come ho detto nel primo post) ...anche se non ho capito come! :muro:
La SeekableByteChannel poi è una classe che da come indicato "vanta" la possibilità di cambiare la "position" del canale ...ma cosa significa ciò? ... nel senso che un programma esterno X può leggere/scrivere e cambiare la posizione del canale? ....certo che per quanto riguarda le spiegazioni potevano impieagre un pò più del loro tempo sforzandosi di spiegare anche i casi di utilizzo! :doh:

PGI-Bis
20-08-2009, 10:54
A me SeekableByteChannel sembra "seekable" esattamente come FileChannel: ti permette di posizionarti in un punto particolare del flusso. Non sarei stupito se il SeekableByteChannel restituito da un Path che punta ad un file fosse effettivamente un FileChannel.

Quanto alla possibilità di creare dei FileSystem virtuali a me pare di aver capito che la faccenda funzioni "a plug-in".

Crei la tua sottoclasse di java.nio.file.spi.FileSystemProvider, la rendi disponibile tramite classpath (impacchettandola in un jar estensione) e sei a posto. Quando richiedi un file che ha un URI tipico del tuo filesystem PAF, la palla viene passata al tuo filesystem.

Non sembra particolarmente complessa come cosa ma non ho mai provato - e di solito quando uno dice "e facile" senza aver provato scopre che non è poi così facile :D.

Frank1962
20-08-2009, 17:52
A me SeekableByteChannel sembra "seekable" esattamente come FileChannel: ti permette di posizionarti in un punto particolare del flusso. Non sarei stupito se il SeekableByteChannel restituito da un Path che punta ad un file fosse effettivamente un FileChannel.
cioè ....vuol dire che in fase di scrittura, per esempio, scrivo 10byte portando la position a 10, poi posso spostarmi in avanti di 10byte alla position 20 e scrivere altri 10byte lasciando quindi i 10byte in mezzo "vuoti" (cioè a zero) ??.... ma questo che senso ha? (intendo tutto ciò in fase di scrittura)

Quanto alla possibilità di creare dei FileSystem virtuali a me pare di aver capito che la faccenda funzioni "a plug-in".

Crei la tua sottoclasse di java.nio.file.spi.FileSystemProvider, la rendi disponibile tramite classpath (impacchettandola in un jar estensione) e sei a posto. Quando richiedi un file che ha un URI tipico del tuo filesystem PAF, la palla viene passata al tuo filesystem.

Non sembra particolarmente complessa come cosa ma non ho mai provato - e di solito quando uno dice "e facile" senza aver provato scopre che non è poi così facile :D.
uhm ..ho un bel pò di ??!?!??!?!? in testa; alur prendiamo un caso pratico e vediamo se siamo sulla medesima lunghezza d'onda: con il mio bel programmino Java avviato sul winzozzz stò "simulando" un file mp3 (con dimensione e attributi come se fosse reale, scritto su hard disk, ma che in realtà e presente solo nella memoria del mio programma) che si trova cartella "Documenti" ....l'utente clikka sul file mp3 per ascoltarlo e si apre VLC ....dopo un pò di secondi l'utente decide di "seekare" l'mp3 e portarlo avanti di un tot di byte ...come faccio ad "ascoltare" l'avvenuto seek da parte dell'utente sul flusso dati in lettura da parte del VLC e quindi fornire in uscita nel flusso i byte corretti per l'ascolto dell'mp3?
Questo è un esempio con VLC in lettura ....prendiamo un esempio in scrittura con il Blocco Note; medesimo file, stavolta .txt, presente nella cartella "Documenti" ...click dell'utente e apertura del file --> l'utente legge il contenuto che cita "Hello World!" e decide di aggiornare il file aggiungendo in mezzo "Hello hard World!" e salvarlo sul disco ....come faccio ad "ascoltare" questa avvenuta scrittura sul flusso dati da parte di un'altro programma? (in questo caso il Blocco Note)
La classe FileSystemProvider come hai citato fornisce un metodo che appunto ritorna un "AsynchronousFileChannel" ...ma come cià dicevo nel primo host non ho capito come poter utilizzare questo canale asincrono per fare tutto ciò con il VLC, Blocco Note o qualsiasi altro programma! :muro:

Grazie a tutti per il vostro tempo, sia a chi lurka che a chi scrive :D

PGI-Bis
20-08-2009, 18:19
Direi che la possibilità di creare filesystem virtuali sia limitata all'ambiente Java: tutti i programmi java che caricano quel plug-in avranno a disposizione quel tipo particolare di accesso ai file.

Da quanto leggo nella javadoc la possibilità di intercettare ciò che i programmi java intendono fare con i file di un certo filesystemprovider deriva dal fatto che il provider stesso opera come factory per i flussi e i percorsi. In tanto può intercettare una richiesta di scorrimento in un canale in quanto il canale che ha precedentemente restituito possiede una tracciabilità di quelle richieste.

Frank1962
20-08-2009, 18:27
Da quanto leggo nella javadoc la possibilità di intercettare ciò che i programmi java intendono fare con i file di un certo filesystemprovider deriva dal fatto che il provider stesso opera come factory per i flussi e i percorsi. In tanto può intercettare una richiesta di scorrimento in un canale in quanto il canale che ha precedentemente restituito possiede una tracciabilità di quelle richieste.
uhm, a dire la verità, mi sono perso un pò.... ma come farei a intercettare questa richiesta di scorrimento? e per l'updating sul canale di dati scritti da terze parti (perchè no anche programmi in java che girano sullo stesso sistema) nun se pò fa?

ps: voglio sottolineare, a meno di fraintendimenti, che il mio chiodo fisso e di capire che cosa fanno gli altri programmi sul canale ...e non il programma Java: alla fine dei conti pensavo che anche una implementazione della interfaccia ByteBuffer potrebbe fare al caso mio, magari creando al tempo i dati richiesti in lettura (ByteBuffer .get()) o quelli in scrittura (ByteBuffer .put()) ....ma il mio problem penso che alla fine sia proprio il sistema nativo di base (winzozo in questo caso) che andrebbe a chiedere tutti i dati presenti nel canale per la scrittura completa del file sull'hardisk e non solo quelli necessari quando un programma legge (e scrive) sul file!

PGI-Bis
20-08-2009, 18:42
IL punto è che quando il plug-in riceve una richiesta "dammi un ByteChannel" quello che gli restituisce può essere una qualsiasi cosa purchè abbia l'interfaccia di ByteChannel.

Diciamo che provider restituisce un channel e che channel è un'interfaccia così scritta:

interface Channel {
void position(long index);
}

Io posso tranquillamenti dire al mio provider che ogni volta che qualcuno chiede un Channel gli sia restiuita un'istanza della classe:

class SpyChannel implements Channel {
private FileChannel channel = qualcosa;

public void position(long index) {
channel.position(index);
Logger.getLogger().log(this + " posizione a " + index);
}
}

Questo per semplificare ovviamente. Ora io ho il mio providere:

public class MyProvider implements FileSystemProvider {

//ipotetico
public Channel openChannel(Path p) {
return new SpyChannel(p);
}
}

Una volta che tutti i metodi delle classi standard che creano o maneggiano file e canali passano per lo stesso punto, che sarebbe l'interfaccia FileSystemProvider, hai il controllo sulle operazioni del programma con i file.

Il File System Virtuale cos'è, è la possibilità che quando l'URI id un file inizia con file:/// il sistema accedal al provider normale, quando l'URI inizia con

mysuperfs:///

il sistema acceda ad un provider personalizzato che, magari, i file e le cartelle le conserva in un database.

Ribadisco comunque che questo è quanto mi pare di capire: le fonti che abbiamo sono quelle là, corriamo il rischio di tirare a indovinare. Ma guardando alle interfacce e alla faccenda del provider plug-in questo mi sembra uno scenario tutt'altro che ipotetico.

Frank1962
20-08-2009, 18:55
si si PGI ...ho capito che ....non ci siamo capiti :D :D :D

Cioè il problema non è a livello Java, o meglio lo è ma, sopratutto, a livello nativo di "dialogo" tra sistema <-> jvm!

Mettiamo che come giustamente hai detto tu mi faccio il mio bel canale, myChannel, con tutto a posto per intercettare le richieste di scrittura e lettura ....se poi però il driver del sistema nativo mi chiede tutti i dati del file perchè li deve scrivere sull'hard disk... bè ecco che il mio "virtual" fa a farsi benedire perchè i dati sono stati scritti sull'hard disk e, oltretutto, quando il file verrà aperto da un programma XY estraneo al mio programma Java, verrano letti e scritti i dati presenti sull'hard disk gestito dall'OS e non quelli presenti nella heap del mio programma java in esecuzione sul sistema :muro:

Frank1962
20-08-2009, 19:17
Ecco questo è uno schizzo (notare la maestria dell'utilizzo della tavoletta grafica che non ho :D) ...come vedi l'interrogativo è se il canale "dialoga" con i driver del filesystem dell'os oppure lascia più liberta di decidere se scrivere i dati sull'hard disk oppure passarli direttamente al pogramma terzo ...praticamente un sorta di pipe bidirezionale!

PGI-Bis
20-08-2009, 19:19
Guarda, da quel punto di vista direi che i pdf non lasciano scampo: lì è specificamente citata l'alta probabilità che il Provider sia affiancato da una controparte nativa che si occuperà poi degli intrallazzi con il sistema operativo. D'altronde già ora tutta la gestione dei File è una grossa interfaccia per oggetti nativi.

Frank1962
20-08-2009, 19:25
Guarda, da quel punto di vista direi che i pdf non lasciano scampo: lì è specificamente citata l'alta probabilità che [b]il Provider sia affiancato da una controparte nativa[b] che si occuperà poi degli intrallazzi con il sistema operativo. D'altronde già ora tutta la gestione dei File è una grossa interfaccia per oggetti nativi.
ergo ...implementazione di un mio FileSystemProvider --> JNI --> C#,C++,IDataObject e schifezze varie :muro: ....peccato, speravo che le NIO2 offrissero qualche cosa di più "concreto"!

PGI-Bis
20-08-2009, 19:27
Be' prima o poi al sistema operativo ci devi arrivare :D.

Frank1962
21-08-2009, 16:38
Be' prima o poi al sistema operativo ci devi arrivare :D.
si infatti ...adesso che una notte è passata e ci ho pensato un pò su in effetti il problema è proprio del "contratto" che c'è nel framework che si occupa di "elaborare" i file: mettiamo un problema semplice, per esempio quello di "aggiornare" un file di testo aggiungeno "in mezzo" una frase ...in effetti nè con OutputStream, nè con FileChannel ho altro è possibile farlo perchè al massimo ti si offre la possibilità di una write o una read e basta ....senza la possibilità di "allargare" un file, a mò di FileSystem intendo.