In questo momento sono totalmente confuso, soprattutto a causa della terminologia, immagino. Qualcuno può guidarmi attraverso le differenze o fornire alcuni collegamenti a materiale a prova di manichino? Soprattutto URI all'URL e Risorsa al file? Per me, sembra che dovrebbero essere la stessa cosa, rispettivamente ...
La terminologia è confusa e talvolta sconcertante, e per lo più nasce dall'evoluzione nel tempo sia di Java come API che come piattaforma. Per capire come questi termini abbiano significato quello che fanno, è importante riconoscere due cose che influenzano il design di Java:
- Compatibilità con le versioni precedenti. Le vecchie applicazioni dovrebbero essere eseguite su installazioni più recenti, idealmente senza modifiche. Ciò significa che una vecchia API (con i suoi nomi e la terminologia) deve essere mantenuta attraverso tutte le versioni più recenti.
- Cross-platform. L'API dovrebbe fornire un'astrazione utilizzabile della sua piattaforma sottostante, che si tratti di un sistema operativo o di un browser.
Descriverò i concetti e come sono nati. Risponderò alle tue altre domande specifiche dopo, perché potrei dover fare riferimento a qualcosa nella prima parte.
Cos'è una "risorsa"?
Un dato astratto e generico che può essere individuato e letto. Detto in modo approssimativo, Java lo usa per fare riferimento a un "file" che potrebbe non essere un file ma che rappresenta un dato dato. Non ha una rappresentazione di classe o interfaccia diretta in Java , ma a causa delle sue proprietà (individuabili, leggibili) è spesso rappresentato da un URL.
Poiché uno dei primi obiettivi di progettazione di Java era quello di essere eseguito all'interno di un browser, come applicazione sandbox (applet!) Con diritti / privilegi / autorizzazione di sicurezza molto limitati, Java fa una chiara differenza (teorica) tra un file (qualcosa sul locale file system) e una risorsa (qualcosa che deve leggere). Questo è il motivo per cui la lettura di qualcosa relativo all'applicazione (icone, file di classe e così via) viene eseguita tramite ClassLoader.getResourcee non tramite la classe File.
Sfortunatamente, poiché "risorsa" è anche un termine generico utile al di fuori di questa interpretazione, è anche usato per nominare cose molto specifiche (es. Classe ResourceBundle , UIResource , Resource ) che non sono, in questo senso, una risorsa.
Le classi principali che rappresentano (un percorso per) una risorsa sono java.nio.file.Path , java.io.File , java.net.URI e java.net.URL .
File (java.io, 1.0)
Una rappresentazione astratta di nomi di percorso di file e directory.
La classe File rappresenta una risorsa raggiungibile tramite il file system nativo della piattaforma . Contiene solo il nome del file, quindi è in realtà più un percorso (vedere più avanti) che la piattaforma host interpreta in base alle proprie impostazioni, regole e sintassi.
Nota che File non deve puntare a qualcosa di locale , ma solo a qualcosa che la piattaforma host comprende nel contesto dell'accesso ai file, ad esempio un percorso UNC in Windows. Se monti un file ZIP come file system nel tuo sistema operativo, File leggerà perfettamente le voci contenute.
URL (java.net, 1.0)
L'URL della classe rappresenta un Uniform Resource Locator, un puntatore a una "risorsa" sul World Wide Web. Una risorsa può essere qualcosa di semplice come un file o una directory, oppure può essere un riferimento a un oggetto più complicato, come una query a un database o a un motore di ricerca.
In tandem con il concetto di risorsa, l'URL rappresenta quella risorsa nello stesso modo in cui la classe File rappresenta un file nella piattaforma host: come una stringa strutturata che punta a una risorsa. L'URL contiene inoltre uno schema che suggerisce come raggiungere la risorsa (con "file:" che è "chiedi alla piattaforma host") e quindi consente di puntare alle risorse tramite HTTP, FTP, all'interno di un JAR e quant'altro.
Sfortunatamente, gli URL hanno una propria sintassi e terminologia, incluso l'uso di "file" e "percorso". Nel caso in cui l'URL sia un file-URL, URL.getFile restituirà una stringa identica alla stringa del percorso del file di riferimento.
Class.getResource restituisce un URL: è più flessibile del file restituito e ha soddisfatto le esigenze del sistema come immaginato all'inizio degli anni '90.
URI (java.net, 1.4)
Rappresenta un riferimento URI (Uniform Resource Identifier).
L'URI è una (leggera) astrazione sull'URL. La differenza tra URI e URL è concettuale e per lo più accademica, ma l'URI è meglio definito in senso formale e copre una gamma più ampia di casi d'uso. Poiché URL e URI sono / non erano la stessa cosa, è stata introdotta una nuova classe per rappresentarli, con i metodi URI.toURL e URL.toURI per spostarsi tra l'uno e l'altro.
In Java, la principale differenza tra URL e URI è che un URL ha l'aspettativa di essere risolvibile , qualcosa da cui l'applicazione potrebbe desiderare un InputStream; un URI è trattato più come una cosa astratta che potrebbe indicare qualcosa di risolvibile (e di solito lo fa), ma cosa significa e come raggiungerlo sono più aperti al contesto e all'interpretazione.
Percorso (java.nio.file, 1.7)
Un oggetto che può essere utilizzato per individuare un file in un file system. Tipicamente rappresenterà un percorso file dipendente dal sistema.
La nuova API di file, iconificata nell'interfaccia Path, consente una flessibilità molto maggiore di quella che la classe File potrebbe offrire. L'interfaccia Path è un'astrazione della classe File e fa parte della New IO File API . Dove File punta necessariamente a un "file" come inteso dalla piattaforma host, Path è più generico: rappresenta un file (risorsa) in un file system arbitrario .
Path elimina la dipendenza dal concetto di file della piattaforma host. Potrebbe essere una voce in un file ZIP, un file raggiungibile tramite FTP o SSH-FS, una rappresentazione multi-root del classpath dell'applicazione, o davvero qualsiasi cosa che possa essere rappresentata in modo significativo attraverso l'interfaccia FileSystem e il suo driver, FileSystemProvider. Porta la potenza del "montaggio" dei file system nel contesto di un'applicazione Java.
La piattaforma host è rappresentata attraverso il "file system predefinito"; quando chiami File.toPath, ottieni un percorso sul file system predefinito.
Ora, se ho un localizzatore che fa riferimento a una classe oa un pacchetto in un file jar, questi due (cioè il percorso di un file stringhe) differiranno?
Improbabile. Se il file jar si trova sul file system locale, non si dovrebbe avere un componente di query, quindi URL.getPathe URL.getFilenecessario restituire lo stesso risultato. Tuttavia, scegli quello che ti serve: gli URL dei file potrebbero non avere in genere componenti di query, ma potrei sicuramente aggiungerne uno comunque.
Infine, e soprattutto, perché ho bisogno di un oggetto File; perché una risorsa (URL) non è sufficiente?
L'URL potrebbe non essere sufficiente perché File ti dà accesso a dati di manutenzione come permessi (leggibili, scrivibili, eseguibili), tipo di file (sono una directory?) E la possibilità di cercare e manipolare il file system locale. Se queste sono le funzionalità di cui hai bisogno, allora File o Path le forniscono.
Non hai bisogno di File se hai accesso a Path. Alcune API meno recenti potrebbero richiedere File, tuttavia.
(E c'è un oggetto Risorsa?)
No, non c'è. Ci sono molte cose chiamate in questo modo, ma non sono una risorsa nel senso di ClassLoader.getResource.
Pathe FileSystem da NIO :)