大きなリソースフォルダをJavaプロジェクトに含めるためのベストプラクティス

Eos

私は、大きなリソースフォルダー(数千の小さな画像を含む構造)へのアクセスが必要なプロジェクトに取り組んでいます。クライアントは、ネイティブインストール(アプリの実行に必要なJVMを含む)を介してアプリを提供したいと考えています。彼は、そのリソースをアプリ内のフォルダーとしてパックしたくありません。これは、最終ユーザーのハードドライブに元のフォルダーと同じ大きさのフォルダー構造が作成されるためです(フォルダーは多くのスペースを必要としませんが、小さなファイルがたくさんあります)。さらに、フォルダをコピーするだけで簡単に盗むことができます。これを考えると、jarファイルがインストール可能でないことがわかっている限り、すべてのアプリをリソースフォルダーとともにjarファイルにパッケージ化することはできません。別の要件は、クライアントがプログラムに新しい機能を追加するために、インストールされたアプリフォルダー構造にいくつかのファイルを追加するための特定の柔軟性を必要とすることです。

それらをjarファイルにパックし、ビルドパスに含めてアクセスしようとしましたが、さまざまなサイトで行ったすべての調査を行っても失敗しました。getResources()を何百万もの方法で試しましたが、jarファイル内に単純なディレクトリを取得することは不可能でしたが、jar外のフォルダから取得するのは非常に簡単です。ディレクトリに含まれるファイルのリストを取得するには、ディレクトリにアクセスする必要があります。

この時点に到着しました。私はこの問題に最善の方法で直面しているかどうかを自問し始めたので、皆さんに質問したいと思います。この要件を備えたネイティブJavaアプリに必要なリソースをどのようにパッケージ化しますか?

ある種の暗号化プロセスを作成して、すべての情報を含む単一のファイルを作成し、実行時に必要に応じて一時的に復号化することも考えていますが、これに対処するためのより簡単でクリーンな方法があると思います。

前もって感謝します

編集:あなたが求めたように、私は私が試したもののコードを追加しています:

これがプロジェクトの構造です

project
├───src
│   ├───main
│   │   └───java
│   │       ├───model <--- where my class is
│   │       ├───controllers
│   │       ├───utilities
│   │       └───views
│   ├───resources <--- this is where is (formerly) accessed the content i need
|   |   ├─── jarfile.jar <--- i've placed file here and included to build path
│   │   └───-various folders and files -
│   └───test
└───target

jarファイル内にはパッケージsrc.resources.blalblabaがあり、この中に必要なフォルダーがあります。

方法1:

getResourcesがjarファイル「。」を置き換えます。「/」を使用してパスで試行:「src / resources / blablabla / folderINeed」、「src / resources / src / resources / blablabla」(重複の可能性があるため)、「folderINeed」、「blablabla / folderINeed」-> URIは常にメッセージ「null」を含むNullPointerException

public void loadContent(String contentPath) throws Exception
{ 
    File resources= null;
    File[] listFiles = null;

    URI uri = getClass().getClassLoader().getResource(contentPath).toURI();
    resources= new File(uri);
    listFiles = resources.listFiles();

    //do some file proccessing and load them
}

方法2:使用されたパス "folderINeed"、 "src / resources / blablabla / folderINeed"、 "blablabla / folderINeed"、 "../../../ resources / blablabla / folderINeed" <--- URLはnullを返しますが、少なくとも、NullPointerExceptionは発生しません。

public void loadContent(String contentPath) throws Exception
{ 
    // conseguimos todas las carpetas de animaciones
    File resources;
    File[] listFiles = null;

    URL url = MyClass.class.getResource(contentPath);
    if (url == null) {
         // error - missing folder
    } else {
        resources = new File(url.toURI());
        listFiles = resources.listFiles();
    }
}

方法3:クラスJarFileを使用した複雑なコードで、私には機能せず、フォルダーではなく単純なファイルを取得するように指示されていました。ここで入手

Eos

私の苦悩:

  • @Joop Egenが彼の回答で言ったように、私の問題の1つは、プロジェクト内のフォルダー構造でした。リソースフォルダーをsrc / main /フォルダーに配置するというMavenの規則に従っていませんでした。これは、私が試したすべてのソリューションに、リソースフォルダーを取得するために必要なスコープがなかったためです。

  • jarファイルがjavaでどのように機能するのかわかりませんでした。javaの場合、.jarファイルは、その中のすべてのファイルへのjarエントリのコレクション(javaのコレクションではありません)です。私の1つのケースでは、.jarファイルはEclipseエクスポートウィザードを使用して作成され、フォルダーへの参照はなく、ファイルへの参照のみが含まれていました。したがって、すべてのコンテンツを含むフォルダを取得することは単純に不可能です。

  • java JarFileクラスを使用してコンテンツを管理しましたが、このクラスはjavaFileクラスのようにファイルを管理するメソッドを提供していません。したがって、他の種類のファイルを使用する場合ほど簡単ではありません。


私が行ったこと .jar内のすべてのファイルエントリを読み取り、関心のあるものを区別するためのコードを開発しました。そして、それらをアプリ内のディレクトリに抽出します。これを行うことで、私はそれらに標準でアクセスでき、必要に応じて、アプリケーションを閉じたときにディレクトリを削除するだけで済みます。私はそれらをjarから直接使用しようとしましたが、jarファイルはzipファイルであるため、OSがzipファイルで行うように、内部ファイルをjarからどこかに追加する必要があります。一時ディレクトリである場合もそうでない場合もあります。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import org.apache.commons.io.FileUtils;

public class App
{
  public static void main(String[] args)
  {
    try
    {

      //needed attributes
      String pathToJar = "./src/main/blablalba/fileName.jar";
      String folderYouWantToRetrieveFromTheJar = "/folderIWant";
      String pathOfFilesWithinTheJar="src/resources/blablabla/"+folderYouWantToRetrieveFromTheJar+"/";
      String tempDirectoryWhereExtract="./src/main/resources/temp";

      //creating the temp directory
      File tempDirectoryReference = new File(tempDirectoryWhereExtract);
      if (!tempDirectoryReference.exists())
      {
        Files.createDirectory(tempDirectoryReference.toPath());
      }

      //searching what entries i need
      JarFile jar = new JarFile(pathToJar);
      final Enumeration<JarEntry> entries = jar.entries(); 
      List<JarEntry> targetEntries = new ArrayList<>();
      while (entries.hasMoreElements())
      {
        JarEntry entry = entries.nextElement();
        //if the entry is what i need 
        if (entry.getName().startsWith(pathOfFilesWithinTheJar))
        { 
          targetEntries.add(entry);
        }
      }
      //extract every target entry from the .jar
      for (JarEntry entry : targetEntries)
      {
        //in order to copy the structure i will get only the point where folderIWant is present
        int index = entry.getName().indexOf(folderYouWantToRetrieveFromTheJar);
        String newTemporaryPath = tempDirectoryReference.getPath().toString()+"/"+entry.getName().substring(index);
        extractFileFromJar(jar, entry, new File(newTemporaryPath));

      }

      jar.close();
      //(optional) clean after use
      FileUtils.deleteDirectory(tempDirectoryReference);


    }
    catch (IOException e)
    {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  public static void extractFileFromJar (JarFile jarFile, JarEntry targetEntry, File destinyPath)
  {
    try
    {
      if (!destinyPath.getParentFile().exists())
      {
        createFolderStructure(destinyPath);
      }
      else
      {
        Files.createFile(destinyPath.toPath());
      }

      InputStream inputStream = jarFile.getInputStream(targetEntry); 
      FileOutputStream outputStream = new java.io.FileOutputStream(destinyPath);
      while (inputStream.available() > 0) {  
          outputStream.write(inputStream.read());
      }
      outputStream.flush();
      outputStream.close();
      inputStream.close();
    }
    catch (IOException e)
    {
      e.printStackTrace();
    }
  }


  private static void createFolderStructure(File destinyPath)
  {
    File parentPath = destinyPath.getParentFile();
    try
    {
      if (parentPath.exists())
      {
          Files.createFile(destinyPath.toPath());
      }
      else
      {
        Files.createDirectories(destinyPath.getParentFile().toPath());
        Files.createFile(destinyPath.toPath());
      }
    }
    catch(IOException e)
    {
      System.err.println(e.getMessage());
    }
  }
}

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

WebappプロジェクトにBootstrapリソースを含めるための一般的なベストプラクティスは何ですか?

分類Dev

大規模なJavaプロジェクトでメモリリークを処理するためのベストプラクティスは?

分類Dev

大きなCSVファイルを作成するためのJava IOのベストプラクティス

分類Dev

プロジェクトにC ++ライブラリを含めるためのベストプラクティス

分類Dev

型を宣言ファイルから外部プロジェクトにエクスポートするためのベストプラクティス

分類Dev

クラスにロックオブジェクト以上のものを含めるためのベストプラクティス

分類Dev

ケースクラスのオブジェクト属性をフィルタリングするためのベストプラクティス

分類Dev

大きなcsvを正規化されたリレーショナルデータベース(複数のテーブルを含む)にインポートするためのベストプラクティスは何ですか

分類Dev

フォロワーなどをユーザーに追加するためのRESTルーティングのベストプラクティス

分類Dev

MVCでリソースファイルを分割するためのベストプラクティス

分類Dev

Cassandra増分バックアップフォルダーをクリーンアップするためのベストプラクティス

分類Dev

大きなアプリケーションでルーティングを指定するためのベストプラクティス

分類Dev

アクティブストレージ:フォームが再表示されるときにアップロードされたファイルを保持/キャッシュするためのベストプラクティス

分類Dev

css / jsにフロントエンドnpmパッケージを含めるためのベストプラクティス?

分類Dev

ページにCSSとJavaScriptを含めるためのベストプラクティスは何ですか?

分類Dev

Mavenでリソースファイルとクラスをパッケージ化するためのベストプラクティス

分類Dev

データオブジェクトをロックするためのベストプラクティス

分類Dev

Javaプロジェクトで外部モジュールを参照するためのベストプラクティス

分類Dev

テストプロジェクトに.cppファイルを含めるためのより良い方法は?

分類Dev

Pythonプロジェクトに.gitignoreファイルを追加するためのベストプラクティス?

分類Dev

gson-任意のタイプのオブジェクトをシリアル化するときにクラス名プロパティを含める方法

分類Dev

既存のフォルダに「gitclone」するためのベストプラクティスは何ですか?

分類Dev

Javaオブジェクトを変換するためのベストプラクティス/パターン

分類Dev

Angularテンプレートにスクリプトを含めるためのベストプラクティスは?

分類Dev

jメーターテストスクリプトで、パフォーマンステストの応答時間をチェックするためにJavaスクリプト、カスケードスタイルシートを除外し、HTMLのみを含めるのはなぜですか?

分類Dev

複数のプロジェクトをgitリポジトリに配置するためのベストプラクティスは何ですか?

分類Dev

リストオブジェクトをリストオブジェクトに変換するためのベストプラクティス

分類Dev

角度7フォームをリセットするためのベストプラクティス

分類Dev

PDFファイルの印刷およびマージ中にメモリリークや不要なメモリ消費を回避するためにJavaでiTextを使用するためのベストプラクティスは何ですか

Related 関連記事

  1. 1

    WebappプロジェクトにBootstrapリソースを含めるための一般的なベストプラクティスは何ですか?

  2. 2

    大規模なJavaプロジェクトでメモリリークを処理するためのベストプラクティスは?

  3. 3

    大きなCSVファイルを作成するためのJava IOのベストプラクティス

  4. 4

    プロジェクトにC ++ライブラリを含めるためのベストプラクティス

  5. 5

    型を宣言ファイルから外部プロジェクトにエクスポートするためのベストプラクティス

  6. 6

    クラスにロックオブジェクト以上のものを含めるためのベストプラクティス

  7. 7

    ケースクラスのオブジェクト属性をフィルタリングするためのベストプラクティス

  8. 8

    大きなcsvを正規化されたリレーショナルデータベース(複数のテーブルを含む)にインポートするためのベストプラクティスは何ですか

  9. 9

    フォロワーなどをユーザーに追加するためのRESTルーティングのベストプラクティス

  10. 10

    MVCでリソースファイルを分割するためのベストプラクティス

  11. 11

    Cassandra増分バックアップフォルダーをクリーンアップするためのベストプラクティス

  12. 12

    大きなアプリケーションでルーティングを指定するためのベストプラクティス

  13. 13

    アクティブストレージ:フォームが再表示されるときにアップロードされたファイルを保持/キャッシュするためのベストプラクティス

  14. 14

    css / jsにフロントエンドnpmパッケージを含めるためのベストプラクティス?

  15. 15

    ページにCSSとJavaScriptを含めるためのベストプラクティスは何ですか?

  16. 16

    Mavenでリソースファイルとクラスをパッケージ化するためのベストプラクティス

  17. 17

    データオブジェクトをロックするためのベストプラクティス

  18. 18

    Javaプロジェクトで外部モジュールを参照するためのベストプラクティス

  19. 19

    テストプロジェクトに.cppファイルを含めるためのより良い方法は?

  20. 20

    Pythonプロジェクトに.gitignoreファイルを追加するためのベストプラクティス?

  21. 21

    gson-任意のタイプのオブジェクトをシリアル化するときにクラス名プロパティを含める方法

  22. 22

    既存のフォルダに「gitclone」するためのベストプラクティスは何ですか?

  23. 23

    Javaオブジェクトを変換するためのベストプラクティス/パターン

  24. 24

    Angularテンプレートにスクリプトを含めるためのベストプラクティスは?

  25. 25

    jメーターテストスクリプトで、パフォーマンステストの応答時間をチェックするためにJavaスクリプト、カスケードスタイルシートを除外し、HTMLのみを含めるのはなぜですか?

  26. 26

    複数のプロジェクトをgitリポジトリに配置するためのベストプラクティスは何ですか?

  27. 27

    リストオブジェクトをリストオブジェクトに変換するためのベストプラクティス

  28. 28

    角度7フォームをリセットするためのベストプラクティス

  29. 29

    PDFファイルの印刷およびマージ中にメモリリークや不要なメモリ消費を回避するためにJavaでiTextを使用するためのベストプラクティスは何ですか

ホットタグ

アーカイブ