2011-12-15 9 views
6

私は2つのリソースフォルダを持っています。Javaのリソース/ソースフォルダにプログラムでファイルを作成しますか?

SRC - ここに私のリソースファイルフォルダ(パッケージ)で編成さ(画像、.propertiesファイル)がされている - ここに私の.javaファイル

リソースです。

プログラムで別の.propertiesファイルをそのリソースフォルダに追加する方法はありますか?

私はこのような何かを試してみました:
public static void savePropertiesToFile(Properties properties, File propertiesFile) throws IOException { 
     FileOutputStream out = new FileOutputStream(propertiesFile); 
     properties.store(out, null); 
     out.close(); 
    } 

と作成した前

new File("/folderInResources/newProperties.properties"); 

しかし、それは、ファイルシステム上のパスを探します。どのようにしてリソースフォルダーを表示させることができますか?

EDIT:私はそれについて何か言いましょう。私はGUIアプリケーションを持っており、2つの言語をサポートしています(リソースフォルダー内の2つの.propertiesファイル)。今ではユーザーがアプリケーションを簡単に翻訳できるオプションを追加しました。終了したら、新しい.propertiesをいくつかの隠しフォルダのディスクに保存し、そこから読み込みます。しかし、現在の言語(resourcesフォルダ)の横に新しい.propertiesファイル(新しい言語)を保存できることを期待していました。私は静的なMessagesクラスを持っています。このクラスは、ディスクと両方のリソースを両方ともリソースフォルダにロードする方法を知っています。しかし、ユーザーがこの他のマシンでこの.jarファイルを使用した場合、その新しい言語は、そのコンピュータ上のディスク上にあり、.jarファイル内ではないため、その新しい言語を使用できません。

答えて

0

リソースはクラスローダーによってロードされ、デフォルトのクラスローダーは頻繁にキャッシュされます。

静的でないファイルシステムからリソースを読み込むために、必要な動作をする独自のクラスローダーが必要です。

+0

@ThorbjørnRavn Andersenもし私がこれを試してみると、 'MyClass.class.getClassLoader()'私にはいくらかの道を与える方法はありません。 – vale4674

+0

リソースを書き込むことはできません。ただし、ファイルシステムからリソースをロードするクラスローダーを使用できます。 –

0

問題はクラスパスに複数のルートディレクトリを含めることができるため、保存するファイルとディレクトリを区別することが難しくなります。

既存のファイルが読み込まれている場合。

File existingFile = ...; 
File parentDirectory = existingFile.getParentFile(); 
new File(parentDirectory, "newProperties.properties"); 

それ以外の場合は、リソースディレクトリで一意であることがわかっているディレクトリでハンドルを取得してください。 (これが正常に動作しているかどうかわからない)

URL url = this.getClass().getResource("/parentDirectory"); 
File parentDirectory = new File(new URI(url.toString())); 
new File(parentDirectory, "newProperties.properties"); 
+0

@ Lionel Portこの組み合わせを試しましたが動作しません。 \t \t 'URL url = FilesUtil.class.getResource("/messages/messages.properties "); \t \t System.out.println(url); \t \tファイルファイル=新しいファイル(url.toURI()); \t \t System.out.println(ファイル); ' 最初の出力は私にディスク上の絶対パスを与えますが、ファイルを作成しようとすると' java.lang.IllegalArgumentException:URIには権限コンポーネントの例外。 Javaのように見えるそれの作業スペース(.jarファイル)の内部に書き込むことはできません。 – vale4674

+0

はい、プロパティファイルが、書き込み権限を持つ展開されたディレクトリにある場合にのみ機能します。申し訳ありませんが、あなたがjarファイルを更新しようとしていたことは気付きませんでした。 –

+0

簡略化することができます。 'new File(parentDirectoryUrl.getFile())' – Ducaz035

6

他の人が触れたように、リソースはClassLoaderで取得されています。二つの電流応答がストレスに失敗しているどのような、しかし、これらの点である:

  • クラスローダが抽象クラスやその他のリソースを取得するプロセスを意味しています。リソースは、ファイルシステム内のファイルである必要はありません。リモートURL、またはあなたまたは他の誰かがjava.lang.ClassLoaderを拡張して実装する可能性のあるものであってもかまいません。
  • クラスローダーは、子/親の委任チェーンに存在します。 ClassLoaderの通常の動作では、まず親からリソースを取得し、そのリソースだけを検索しますが、一部のクラスローダーは逆の順序をとります(サーブレットコンテナなど)。どのような場合でも、クラスローダーの場所を特定して、それを置くべきものを特定する必要があります。また、クライアントコードのリソース要求を「盗む」かもしれません。
  • Lionel Portが指摘しているように、単一のClassLoaderであっても、複数の場所からロードされることがあります。
  • クラスローダーは、クラスをロードするために使用されます。プログラムがクラスをロードする場所にファイルを書き込むことができる場合、ユーザーが実行中のアプリケーションにコードを挿入する可能性があるため、これはセキュリティ上のリスクになりがちです。

ショートバージョン:しないでください。 「リソースを得ることができるリソースのようなもののリポジトリ」というコンセプトのためのより抽象的なインタフェースを作成し、「リソースを得ることができるリソースのようなもののリポジトリ」のサブインターフェイスを作成します。後者は、両方ともClassLoader.getContextClassLoader().getResource()(クラスパスを検索するため)を使用する方法で実装し、失敗した場合は、プログラムがある場所から追加した可能性のあるものを取得するために他のメカニズムを使用します。

+0

@ sacundimコメントが大きすぎるため、私は自分の質問を編集しました。 – vale4674

0

コンパイルサブフォルダ(「/対象/クラス」、「ターゲット/テスト・クラス」)のメインプロジェクトフォルダをカットし、あなたとあなたのプロジェクトのフォルダを再構築するための基本的なパスを持っている:

import java.io.File; 
import java.io.IOException; 
import java.net.URISyntaxException; 

public class SubfolderCreator { 

public static void main(String... args) throws URISyntaxException, IOException { 
    File newResourceFolder = createResourceSubFolder("newFolder"); 
} 

private static File createResourceSubFolder(String folderName) throws URISyntaxException, IOException { 
    java.net.URL url = SubfolderCreator.class.getResource("/EXISTING_SUBFOLDER/"); 
    File fullPathToSubfolder = new File(url.toURI()).getAbsoluteFile(); 
    String projectFolder = fullPathToSubfolder.getAbsolutePath().split("target")[0]; 
    File testResultsFolder = new File(projectFolder + "src/test/resources/" + folderName); 
    if (!testResultsFolder.exists()) { 
     testResultsFolder.mkdir(); 
    } 
    return testResultsFolder; 
} 
} 
0

次のコードをクラスファイルとともにclassesディレクトリに書き込みます。

他の人も注意したように、クラスファイルを上書きすることに注意してください。あなたの新しいファイルを別のディレクトリに置くのがベストです。ただし、そのディレクトリはすでに存在する必要があります。作成するには、ソース内のリソース内にサブディレクトリを作成します。おそらく空のファイルが含まれています。たとえば、src\main\resources\dir\empty.txtです。

public class WriteResource { 
    public static void main(String[] args) throws FileNotFoundException { 
     String thing = "Text to write to the file"; 
     String dir = WriteResource.class.getResource("/").getFile(); 
     //String dir = WriteResource.class.getResource("/dir").getFile(); 
     OutputStream os = new FileOutputStream(dir + "/file.txt"); 
     final PrintStream printStream = new PrintStream(os); 
     printStream.println(thing); 
     printStream.close(); 
    } 
} 

これはトリックですが、厳密に制御された環境の外でこれを展開することについては緊張しています。私は許可されていない人が私のclassesディレクトリに書き込むという考えが本当に好きではありません!

関連する問題