2016-09-01 10 views
0

各jarのルートレベルにあるプロパティファイル "version.properties"からプロパティ "product.build.number"を読み取る必要があります。私の素朴なアプローチは次のとおりです。jar内のプロパティファイルから特定のプロパティを読み込みます

private static int getProductBuildNumber(File artefactFile) throws FileNotFoundException, IOException 
    { 
    try (ZipInputStream zip = new ZipInputStream(new FileInputStream(
     artefactFile))) 
    { 

     Set<String> possClasses = new HashSet<>(); 

     for (ZipEntry entry = zip.getNextEntry(); entry != null; entry = zip 
      .getNextEntry()) 
     { 
     if (!entry.isDirectory() && entry.getName().toLowerCase().equals(
      "version.properties")) 
     { 
      List<String> lines = IOUtils.readLines(zip, (String) null); 

      for (String line : lines) 
      { 
      if (line.startsWith("product.build.number")) 
      { 
       String[] split = line.split("="); 
       if (split.length == 2) 
       { 
       return Integer.parseInt(split[1]); 
       } 

      } 
      } 

     } 
     } 
    } 

    throw new IOException("product.build.number not found."); 

    } 

もっとエレガントで信頼できる方法があると思います。何か案は?

+0

あなたのアプローチは正しく見えます – vsminkov

答えて

3

(未テスト)のようなものを試してみてください:

private static int getProductBuildNumber(Path artefactFilePath) throws IOException{ 
    try(FileSystem zipFileSystem = FileSystems.newFileSystem(artefactFilePath, null)){ 
     Path versionPropertiesPath = zipFileSystem.getPath("/version.properties"); 
     Properties versionProperties = new Properties(); 
     try (InputStream is = Files.newInputStream(versionPropertiesPath)){ 
      versionProperties.load(is); 
     } 
     return Integer.parseInt(versionProperties.getProperty("product.build.number")); 
    } 
} 
+0

私はそれがメモリを開梱しないことに注意しなければなりません。書き込み可能なディレクトリが必要です。 – vsminkov

+0

@vsminkovあなたが何を意味するか分かりません。 JREに同梱されているzipファイルシステムプロバイダは、NIO.2 File APIを使用してzipファイルにアクセスできます。参照:http://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html – Puce

+0

このソリューションでは、アンパックを実行するために追加のディスク領域が必要です(ここでは[example](http ://stackoverflow.com/questions/24863465/java-zip-file-system-provider-readonly-on-remote-drive-windows))。 'ZipInputStream'はメモリ内のアンパックを行います。 – vsminkov

0

あなたのクラスパスにある.jarファイルがあるかどうか言っていません。

彼らはあなたのクラスパスにある場合は、エントリを読み取るためにClass.getResourceAsStreamを使用する必要があります。ファイルからURL:

try (InputStream propStream = getClass().getResourceAsStream("/version.properties")) { 
    // ... 
} 

彼らは.jarファイル場合は、あなたのクラスパスに含まれていない、あなたはjarファイルを作成する必要があります。このようなURLのフォーマットは、JarURLConnection documentationに記載されています。

private static int getProductBuildNumber(Path artefactFile) 
throws IOException { 
    URL propsURL = new URL("jar:" + artefactFile.toUri() + "!/version.properties"); 
    try (InputStream propStream = propsURL.openStream()) { 
     // ... 
    } 
} 

かかわらず、データの場所の、あなたは常にプロパティを読み取ることがPropertiesクラスを使用する必要があります。java.io.Fileのは廃止され、そしてあなたがいつも代わりにPathを使用する必要があること

注意。あなたは、クラスパスの外にjarファイルからプロパティファイルを読んでいる場合(プロパティファイルを自分で解析すると、あなたがコメントを考慮して持っていることを意味、Unicodeは、継続行をエスケープし、すべての可能な名前/値の区切り。)

Properties props = new Properties(); 
try (InputStream propStream = getClass().getResourceAsStream("/version.properties")) { 
    props.load(propStream); 
} 

int buildNumber = Integer.parseInt(
    props.getProperty("product.build.number")); 
+0

getClass()。getResourceAsStreamはここでは機能しません。(複数のjarファイルを使用している場合は、/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.java#l1089)メソッドがアンパック時に呼び出されます。同じ場所にあるversion.propertiesファイル - デフォルトのクラスローダーは最初のものだけを表示します) – Puce

関連する問題