2009-11-07 7 views
2

Lorsque je charge des données dans mon programme Java, j'utilise généralement FileInputStream. Cependant, je déploie le programme en tant que fichier jar et webstart, donc je dois utiliser getRessource() ou getRessourceAsStream() pour charger les données directement à partir du fichier jar.Chargement de fichiers JAR pendant le déploiement ou le développement

maintenant il est assez ennuyeux de toujours passer ce code entre le développement et le déploiement?

est-il un moyen autmate cela? C'est-à-dire qu'il existe un moyen de savoir si le code est exécuté à partir d'un pot ou non?

lorsque je tente de charger withoug pot comme ceci:

InputStream is = this.getClass().getResourceAsStream("file.txt"); 

le InputStream retourné est tout simplement nul, bien que le fichier est sans aucun doute dans le répertoire racine de l'application.

merci!

Répondre

7

Pourquoi utilisez-vous FileInputStream pendant le développement? Pourquoi ne pas simplement utiliser getResourceAsStream dès le début? Tant que vous placez vos fichiers dans un endroit approprié dans votre classpath, vous ne devriez pas avoir de problèmes. Il peut toujours s'agir d'un fichier dans le système de fichiers local plutôt que dans un fichier jar.

Il est utile de développer en pensant à l'environnement de déploiement final.

EDIT: Si vous voulez quelque chose dans le répertoire racine de votre classpath, vous devez soit utiliser:

InputStream x = getClass().getResourceAsStream("/file.txt"); 

ou

InputStream x = getClass().getClassLoader().getResourceAsStream("file.txt"); 

Fondamentalement Class.getResourceAsStream résoudra les ressources relatives à l'emballage contenant la classe; ClassLoader.getResourceAsStream résout tout ce qui concerne le paquet "root".

+0

la cause il ne semble pas fonctionner si les fichiers se trouvent dans les sous-répertoires – clamp

+0

qui suggère que vous le faire un peu mal. Cela fonctionne certainement bien avec les sous-répertoires, si vous demandez la bonne ressource. S'il vous plaît donner un exemple détaillé, et nous pouvons vous aider. –

+0

merci, j'ai édité mon post principal. – clamp

3

Vous pouvez toujours lire vos données en tant que ressource. Vous devez seulement ajouter le chemin où les données se trouvent à votre chemin de classe.

Si vos données reste vous aurez accès à WEB-INF/somewhere/mydata.txt dans votre fichier jar, avec:

getClass().getResourceAsStream("/WEB-INF/somewhere/mydata.txt") 

Maintenant, si vous créez un répertoire de développement /devel/WEB-INF/somewhere/mydata.txt et mettez /devel à votre classpath, votre code fonctionnera dans le développement et production.

EDIT après explication en question:

Dans votre cas this.getClass().getResourceAsStream("mydata.txt") la ressource est tirée de la même position où le ClassFile de this est tiré. Si vous voulez garder ceci, alors vous devez créer un répertoire /devel/<path of package>/mydata.txt et ajouter de nouveau /devel à votre classpath.

0

Que diriez-vous de définir une propriété système dans votre environnement de développement, via le commutateur -D? par exemple.java -D: myPropertyName = mypropertyvalue

Vous pouvez définir la propriété dans les scripts de fourmis dans votre environnement de dev, d'autres environnements ne reçoivent pas la propriété: par exemple

public static boolean isDevEnvironment(){ return System.getProperty("mypropertyname")!=null;} 

Vous trouverez peut-être une meilleure façon de le pirater de l'un des existants System Properties

0

Si un fichier est considéré comme faisant partie de votre application déployée (par opposition à faire partie de l'installation des fichiers spécifiques) et peut être localisé à travers le classpath puis considérer simplement en utilisant toujours getResourceAsStream car cela fonctionne quel que soit le schéma de déploiement réel tant qu'il se trouve dans le classpath.

Vous pouvez également trouver les informations disponibles à partir de la pertinente JVM (si cela est autorisé par le responsable de la sécurité):

// Get the location of this class 
    Class cls = this.getClass(); 
    ProtectionDomain pDomain = cls.getProtectionDomain(); 
    CodeSource cSource = pDomain.getCodeSource(); 
    URL loc = cSource.getLocation(); // file:/c:/almanac14/examples/ 

http://www.exampledepot.com/egs/java.lang/ClassOrigin.html?l=rel

0

Il ne devrait pas y avoir de différence entre le développement vs déploiement, IHMO. Classloader.getResource ou getResourceAsStream fonctionne bien, vous pouvez lire les ressources et même les écrire. Vous pouvez écrire votre propre Protocol handles et accéder à tout comme une URL/URI, ce qui vous permet de lire et d'écrire des ressources et permet également d'identifier correctement qui fournit réellement la ressource. Le seul problème est si un URLStreamHandlerFactory est déjà enregistré (dans une application J2EE, le conteneur peut installer une usine et vous n'avez aucun moyen d'aller plus loin et d'installer le vôtre) et vous ne pouvez pas utiliser vos gestionnaires "n'importe où" . Sachant cela, il est préférable d'implémenter vos propres "ressources". À ce moment-là, quand j'en ai eu besoin, je n'ai pas pu trouver quelque chose comme ça, alors j'ai dû implémenter mon propre ResourceManager. Pour moi, il semble plus intuitive pour accéder à une ressource comme

Resource layout = ResourceManager.resolve("view://layout/main.jsp") 

au lieu de

URL layout = Classloader.getResource("some_package/view/layout/main.jsp") 
Questions connexes