2016-05-09 9 views
1

jarファイルlangdetect.jarがあります。 それはクラスLanguageDetectioncom/langdetectパッケージであり、画像jarファイル内のフォルダのパス

shows the project structure inside the jar

に示す階層構造を持っています。 jarファイルを実行している間に上記のクラスからprofiles.smフォルダのパスにアクセスする必要があります。

ありがとうございます。

+0

あなたはこれを見ましたか?助けるかもしれないhttp://stackoverflow.com/questions/573679/open-resource-with-relative-path-in-java; jarかどうかは、クラスパス内にある限り同じです。 – Preuk

+0

DetectorFactory.loadProfile(LanguageDetection.class.getResource( "profiles.sm")。getPath());を使用してみました。 しかし助けません –

答えて

2

Jarファイルは、Zipファイル以外の何ものでもなく、Javaではそれらを処理するためのサポートが用意されています。

Java 6の(以前の)

あなたはZipFileとしてjarファイルを開いて、それのエントリを反復処理することができます。各エントリは、ファイル内に完全なパス名を持ちます。相対パス名のようなものはありません。あなたは気をつけなければなりませんが、zipファイルでは絶対的ですが、すべてのエントリーは '/'で始まらないので、必要な場合は追加する必要があります。次のスニペットは、クラスファイルのパスを取得します。 classNameはあなたがJARファイルのJava7ファイルシステムのサポートを使用してJARファイルを開くことができ、.classで終了する、すなわちLanguageDetection.class

String getPath(String jar, String className) throws IOException { 
    final ZipFile zf = new ZipFile(jar); 
    try { 
     for (ZipEntry ze : Collections.list(zf.entries())) { 
      final String path = ze.getName(); 
      if (path.endsWith(className)) { 
       final StringBuilder buf = new StringBuilder(path); 
       buf.delete(path.lastIndexOf('/'), path.length()); //removes the name of the class to get the path only 
       if (!path.startsWith("/")) { //you may omit this part if leading/is not required 
        buf.insert(0, '/'); 
       } 
       return buf.toString(); 
      } 
     } 
    } finally { 
     zf.close(); 
    } 
    return null; 
} 

Javaの7/8

を持っています。これにより、通常のFileSystemのようにjarファイルを操作することができます。だから、あなたがあなたのファイルを見つけてそれからパスを得るまで、あなたはfileTreeを歩くことができます。次の例ではJava8 StreamsとLambdasを使用していますが、Java7のバージョンはこれから派生できますが、少し大きいかもしれません。

Path jarFile = ...; 

Map<String, String> env = new HashMap<String, String>() {{ 
     put("create", "false"); 
    }}; 

try(FileSystem zipFs = newFileSystem(URI.create("jar:" + jarFileFile.toUri()), env)) { 
    Optional<Path> path = Files.walk(zipFs.getPath("/")) 
          .filter(p -> p.getFileName().toString().startsWith("LanguageDetection")) 
          .map(Path::getParent) 
          .findFirst(); 
    path.ifPresent(System.out::println); 
} 

あなたの特定の問題

上記の解決策は、JARまたはZIP内のパスを見つけるためのですが、おそらくあなたの問題への解決策ではないかもしれません。

私はあなたの問題を正しく理解しているかどうかはわかりません。私が見ている限り、あなたはクラスフォルダー内のパスに任意の目的でアクセスしたいと思っています。その問題は、クラス/リソース検索メカニズムがフォルダにのみ適用され、ファイルには適用されないということです。近くにあるコンセプトはパッケージですが、それは常にクラスにバインドされています。

したがって、getResource()メソッドを使用してアクセスする具体的なファイルが常に必要です。たとえば、MyClass.class.getResource(/path/to/resource.txt)となります。

リソースはすなわち/com/languagedetect/profile.sm/にあなたがそのパッケージには、たとえば、参照クラスからクラスLanguageDetectionをパスを構築する可能性があり、このからの絶対パスを引き出す、profiles.smフォルダクラスに比べて、そのパッケージ内に配置されている場合プロフィール。SMパス:

String basePath = "/" + LanguageDetection.class.getPackage().getName().replaceAll("\\.", "/") + "/profiles.sm/"; 
URL resource = LanguageDetection.class.getResource(basePath + "myResource.txt"); 

一つだけprofiles.sm jarファイルのルートにがある場合は、単にあなたが/profiles.sm内のリソースを持つ複数のjarファイルを持っている場合、あなたはすべてへのアクセスを得ることができ

String basePath = "/profiles.sm/"; 
URL resource = LanguageDetection.class.getResource(basePath + "myResource.txt"); 

のために行きますへのzip/jarファイルにアクセスしなくても、それは不可能ですどのような場合には、クラス

for(URL u : Collections.list(LanguageDetection.class.getClassLoader().getResources("/profiles.sm/yourResource"))){ 
     System.out.println(u); 
    } 

のURLからJarファイルを抽出し、その後クラスローダを経由して、それらのとこのパスまたはフォルダの内容は、クラスパス内のパッケージまたはフォルダ内のクラスまたはリソースの参照をJavaがサポートしていないために発生します。 Reflections libを使用するか、上のzipの例を使用して、検出されたjarの内容を追加読み込むことで、上記のClassLoaderの例を拡張できます。

+0

こんにちはgerald、ありがとう、しかし私はjre1.6で私のjarファイルを実行する必要があります。いくつかの代替を必要とします。 –

関連する問題