2010-09-29 11 views
1

J'essaie de faire en sorte que mon application charge une ressource (fichier binaire) de manière transparente:Ouvrir le fichier; essayez d'abord le système de fichiers, puis les fichiers JAR

Si le fichier existe sous le répertoire actuel, ouvrez-le.
Sinon, essayez de chercher dans le fichier JAR actuel, le cas échéant.
Sinon, essayez de chercher dans d'autres fichiers JAR. (Cette option est facultative et je ne me dérange pas spécifier explicitement quels fichiers JAR.)

Jusqu'à présent, je sais de File qui ouvre un fichier local et ClassLoader qui a getResource* pour le contenu JAR.

Y at-il une classe qui combine les deux? Sinon, comment dois-je l'écrire moi-même? Dois-je écrire un ClassLoader qui vérifie également le système de fichiers local? En utilisant File? (Je suis très familier avec Java et ne sais même pas ce qui est un bon type de retour. InputStream?)

Merci

P.S. Par "fichier", je veux dire "chemin", par ex. "data/texture1.png".

Répondre

5

Faire les # 1 et # 3 est assez facile. Faire # 2 (juste en regardant dans le JAR courant seulement) est beaucoup plus difficile car il vous faut comprendre ce que JAR vous

Si vous voulez vérifier le système de fichiers d'abord, sinon charger de classpath, il serait quelque chose comme:

public java.io.InputStream loadByName(String name) { 
    java.io.File f = new java.io.File(name); 
    if (f.isFile()) { 
    return new FileInputStream(f); 
    } else { 
    return getClass().getResource(name); 
    } 
} 

Si vous préférez d'abord charger le même fichier JAR, vous devez déterminer où il se trouve. Consultez Determine which JAR file a class is from pour plus d'informations sur la détermination du fichier JAR à partir duquel vous voulez charger la ressource.

+0

J'avais peur que je pourrais avoir besoin d'une fonction comme ça :(- Merci pour le pointeur vers l'autre question BTW. – aib

3

Un URLClassLoader devrait être capable de charger les deux et d'essayer le chemin du fichier en premier si le chemin du fichier est sur le chemin de la classe devant le jar.


En ce qui concerne vos commentaires:

+0

Ah, super. Cela pourrait être exactement ce que je cherche. – aib

+0

Et en effet c'est! Une question cependant: Pourquoi ne puis-je pas utiliser 'new URL (" file: foo.jar!/Data ")'? Je n'arrive pas à utiliser '! /' Du tout! – aib

+0

Err et encore une chose, il semble préférer le fichier dans le JAR indépendamment de l'ordre dans lequel je donne les chemins po – aib

1

Le fichier jar et le répertoire en cours ne sont pas des concepts dans la machine virtuelle Java, comme ils le sont lorsque vous exécutez un script shell. Vous devrez spécifier un répertoire à utiliser pour charger les fichiers qui vous intéressent, comme une propriété de système lors de l'exécution de la machine virtuelle Java:

java -Ddirectory.to.scan=/home/aib 

Prenez ensuite cette propriété:

String dir = System.getProperty("directory.to.scan"); 

Maintenant, quand on parle de fichiers JAR, tous les fichiers JAR spécifiés explicitement sur le chemin de classe lorsque vous démarrez la JVM sont chargés par le ClassLoader.Vous pouvez obtenir le ClassLoader d'une classe spécifique:

InputStream is = <Your class>.class.getClassLoader().getResourceAsStream("binary file"); 

Notez que tout fichier jar chargé par le chargeur de classe actuelle est recherchée.