Java LanguageRisorse (sul classpath)


introduzione

Java consente il recupero di risorse basate su file memorizzate all'interno di un JAR insieme a classi compilate. Questo argomento si concentra sul caricamento di tali risorse e sulla loro disponibilità per il tuo codice.

Osservazioni

Una risorsa è data da file con un nome simile a un percorso, che risiede nel classpath. L'uso più comune delle risorse è il raggruppamento di immagini di applicazioni, suoni e dati di sola lettura (come la configurazione di default).

È possibile accedere alle risorse con i metodi ClassLoader.getResource e ClassLoader.getResourceAsStream . Il caso d'uso più comune è disporre di risorse inserite nello stesso pacchetto della classe che le legge; i metodi Class.getResource e Class.getResourceAsStream servono questo caso di utilizzo comune.

L'unica differenza tra un metodo getResource e il metodo getResourceAsStream è che il primo restituisce un URL, mentre quest'ultimo apre quell'URL e restituisce un InputStream.

I metodi di ClassLoader accettano un nome di risorsa simile a un percorso come argomento e ricercano ogni posizione nel classpath del ClassLoader per una voce corrispondente a tale nome.

  • Se una posizione del percorso di classe è un file .jar, una voce di jar con il nome specificato è considerata una corrispondenza.
  • Se una posizione del percorso di classe è una directory, un file relativo in tale directory con il nome specificato è considerato una corrispondenza.

Il nome della risorsa è simile alla porzione di percorso di un URL relativo. Su tutte le piattaforme, utilizza le barre ( / ) come separatori di directory. Non deve iniziare con una barra.

I metodi corrispondenti di Class sono simili, ad eccezione di:

  • Il nome della risorsa può iniziare con una barra, nel qual caso la barra iniziale viene rimossa e il resto del nome viene passato al metodo corrispondente di ClassLoader.
  • Se il nome della risorsa non inizia con una barra, viene considerato come relativo alla classe il cui metodo getResource o getResourceAsStream viene chiamato. Il nome effettivo della risorsa diventa package / name , dove package è il nome del pacchetto a cui appartiene la classe, con ogni periodo sostituito da una barra, e name è l'argomento originale dato al metodo.

Per esempio:

package com.example;

public class ExampleApplication {
    public void readImage()
    throws IOException {

        URL imageURL = ExampleApplication.class.getResource("icon.png");

        // The above statement is identical to:
        // ClassLoader loader = ExampleApplication.class.getClassLoader();
        // URL imageURL = loader.getResource("com/example/icon.png");

        Image image = ImageIO.read(imageURL);
    }
}

Le risorse dovrebbero essere collocate in pacchetti con nome, piuttosto che nella radice di un file .jar, per lo stesso motivo le classi sono collocate in pacchetti: per evitare collisioni tra più fornitori. Ad esempio, se più file .jar si trovano nel classpath e più di uno di essi contiene una voce config.properties nella sua radice, le chiamate ai metodi getResource o getResourceAsStream restituiranno i file config.properties da qualsiasi .jar è elencato per primo in il classpath. Questo comportamento non è prevedibile in ambienti in cui l'ordine del classpath non è sotto il controllo diretto dell'applicazione, come Java EE.

Tutti i metodi getResource e getResourceAsStream restituiscono null se la risorsa specificata non esiste. Poiché le risorse devono essere aggiunte all'applicazione al momento della compilazione, le loro posizioni dovrebbero essere note al momento della scrittura del codice; un errore nel trovare una risorsa in fase di esecuzione è in genere il risultato di un errore del programmatore.

Le risorse sono di sola lettura. Non c'è modo di scrivere su una risorsa. Gli sviluppatori principianti spesso commettono l'errore di assumere che dal momento che la risorsa è un file fisico separato durante lo sviluppo in un IDE (come Eclipse), sarà sicuro trattarlo come un file fisico separato nel caso generale. Tuttavia, questo non è corretto; le applicazioni sono quasi sempre distribuite come archivi come file .jar o .war e, in questi casi, una risorsa non sarà un file separato e non sarà scrivibile. (Il metodo getFile della classe URL non è una soluzione per questo, nonostante il suo nome, restituisce semplicemente la porzione di percorso di un URL, che non è in alcun modo garantito che sia un nome file valido).

Non esiste un modo sicuro per elencare le risorse in fase di runtime. Ancora una volta, poiché gli sviluppatori sono responsabili dell'aggiunta di file di risorse all'applicazione al momento della compilazione, gli sviluppatori dovrebbero già conoscere i loro percorsi. Mentre ci sono soluzioni alternative, non sono affidabili e alla fine falliranno.

Risorse (sul classpath) Esempi correlati