リソースへのパスを取得しようとしていますが、運がありません。
これは機能します(IDEとJARの両方)が、この方法ではファイルへのパスを取得できず、ファイルの内容のみが取得できます。
ClassLoader classLoader = getClass().getClassLoader();
PrintInputStream(classLoader.getResourceAsStream("config/netclient.p"));
これを行う場合:
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("config/netclient.p").getFile());
結果は次のとおりです。Java.io.FileNotFoundException: file:/path/to/jarfile/bot.jar!/config/netclient.p (No such file or directory)
リソースファイルへのパスを取得する方法はありますか?
これは意図的なものです。 「ファイル」の内容は、ファイルとして利用できない場合があります。 JARファイルまたは他の種類のリソースの一部である可能性のあるクラスとリソースを扱っていることに注意してください。クラスローダーは、リソースにファイルハンドルを提供する必要はありません。たとえば、jarファイルはファイルシステム内の個々のファイルに展開されていない場合があります。
Java.io.Fileが絶対に必要な場合、Java.io.Fileを取得することでできることはすべて、ストリームを一時ファイルにコピーして同じことを行うことができます。
リソースをロードするときは、次の違いに注意してください。
getClass().getClassLoader().getResource("com/myorg/foo.jpg") //relative path
そして
getClass().getResource("/com/myorg/foo.jpg")); //note the slash at the beginning
この混乱は、リソースをロードするときにほとんどの問題を引き起こしていると思います。
また、画像を読み込むときは、getResourceAsStream()
を使用する方が簡単です:
BufferedImage image = ImageIO.read(getClass().getResourceAsStream("/com/myorg/foo.jpg"));
本当にJARアーカイブから(非イメージ)ファイルをロードする必要がある場合、これを試してみてください。
File file = null;
String resource = "/com/myorg/foo.xml";
URL res = getClass().getResource(resource);
if (res.getProtocol().equals("jar")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile("tempfile", ".tmp");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.close();
file.deleteOnExit();
} catch (IOException ex) {
Exceptions.printStackTrace(ex);
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
if (file != null && !file.exists()) {
throw new RuntimeException("Error: File " + file + " not found!");
}
一行の答えは-
String path = this.getClass().getClassLoader().getResource(<resourceFileName>).toExternalForm()
基本的にgetResource
メソッドはURLを提供します。このURLから、toExternalForm()
を呼び出してパスを抽出できます
参照:
私はこの問題をいじくり回しましたが、実際には解決策が見つからなかったので、奇妙なことに十分です!多くの場合、作業ディレクトリはJARのディレクトリではありません。特に、Windowsの[スタート]メニューからJAR(または任意のプログラム)を実行する場合はそうです。だからここに私がやったことがあり、それはJARの場合と同様に、JARの外部から実行される.classファイルに対しても機能します。 (Windows 7でのみテストしました。)
try {
//Attempt to get the path of the actual JAR file, because the working directory is frequently not where the file is.
//Example: file:/D:/all/Java/TitanWaterworks/TitanWaterworks-en.jar!/TitanWaterworks.class
//Another example: /D:/all/Java/TitanWaterworks/TitanWaterworks.class
PROGRAM_DIRECTORY = getClass().getClassLoader().getResource("TitanWaterworks.class").getPath(); // Gets the path of the class or jar.
//Find the last ! and cut it off at that location. If this isn't being run from a jar, there is no !, so it'll cause an exception, which is fine.
try {
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('!'));
} catch (Exception e) { }
//Find the last / and cut it off at that location.
PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(0, PROGRAM_DIRECTORY.lastIndexOf('/') + 1);
//If it starts with /, cut it off.
if (PROGRAM_DIRECTORY.startsWith("/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(1, PROGRAM_DIRECTORY.length());
//If it starts with file:/, cut that off, too.
if (PROGRAM_DIRECTORY.startsWith("file:/")) PROGRAM_DIRECTORY = PROGRAM_DIRECTORY.substring(6, PROGRAM_DIRECTORY.length());
} catch (Exception e) {
PROGRAM_DIRECTORY = ""; //Current working directory instead.
}
netclient.p
がJARファイル内にある場合、そのファイルは他のファイル内にあるため、パスはありません。その場合、使用できる最適なパスは、実際にはfile:/path/to/jarfile/bot.jar!/config/netclient.p
です。
Jarファイル内のパスを理解する必要があります。
単に相対的なものを指します。したがって、\src\main\resources
ディレクトリの下のfoo.jarにあるファイル(myfile.txt)がある場合(Mavenスタイル)。次のように参照します。
src/main/resources/myfile.txt
jar -tvf myjar.jar
を使用してjarをダンプすると、jarファイル内に出力と相対パスが表示され、FORWARD SLASHESが使用されます。
これは、jarリソースからの不完全な一時ファイルコンテンツコピーを回避し、一意の一時ファイル名を持つために、ストリームフラッシュとクローズを使用するユーザーTombartの同じコードです。
File file = null;
String resource = "/view/Trial_main.html" ;
URL res = getClass().getResource(resource);
if (res.toString().startsWith("jar:")) {
try {
InputStream input = getClass().getResourceAsStream(resource);
file = File.createTempFile(new Date().getTime()+"", ".html");
OutputStream out = new FileOutputStream(file);
int read;
byte[] bytes = new byte[1024];
while ((read = input.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
input.close();
file.deleteOnExit();
} catch (IOException ex) {
ex.printStackTrace();
}
} else {
//this will probably work in your IDE, but not from a JAR
file = new File(res.getFile());
}
私の場合、PathではなくURLオブジェクトを使用しました。
ファイル
File file = new File("my_path");
URL url = file.toURI().toURL();
クラスローダーを使用したクラスパスのリソース
URL url = MyClass.class.getClassLoader().getResource("resource_name")
コンテンツを読む必要があるときは、次のコードを使用できます。
InputStream stream = url.openStream();
また、InputStreamを使用してコンテンツにアクセスできます。
ファイルはファイルシステム内のファイルの抽象化であり、ファイルシステムはJARの内容について何も知りません。
URIで試してください。あなたの目的に役立つjar://プロトコルがあると思います。
Jarのressourcesフォルダー(Java/main/resources)にファイルを追加します(imports.xmlという名前のxmlファイルを追加したと仮定します) )、その後、次のようなスプリングを使用する場合はResourceLoader
を注入します
@Autowired
private ResourceLoader resourceLoader;
ツアー機能内で、ファイルをロードするために以下のコードを記述します。
Resource resource = resourceLoader.getResource("classpath:imports.xml");
try{
File file;
file = resource.getFile();//will load the file
...
}catch(IOException e){e.printStackTrace();}
private static final String FILE_LOCATION = "com/input/file/somefile.txt";
//Method Body
InputStream invalidCharacterInputStream = URLClassLoader.getSystemResourceAsStream(FILE_LOCATION);
これをgetSystemResourceAsStream
から取得するのが最適なオプションです。ファイルまたはURLではなく入力ストリームを取得することにより、JARファイル内でスタンドアロンとして機能します。
少し遅いかもしれませんが、私のライブラリ KResourceLoader を使用して、jarからリソースを取得できます。
File resource = getResource("file.txt")
次のパスは私のために働いた:classpath:/path/to/resource/in/jar
Jarファイルの場合、リソースは絶対にパッケージ階層にあります(ファイルシステム階層ではありません)。したがって、「./ default.conf」という名前のリソースをロードするクラスcom.example.Sweetがある場合、リソースの名前は「/com/example/default.conf」として指定されます。
しかし、それが瓶に入っている場合、それはファイルではありません...
述べられているように、これはリソースをロードする最適な方法ではありませんが、Java.io.File
参照が絶対に必要な場合は、次を試してください:
URL url = null;
try {
URL baseUrl = YourClass.class.getResource(".");
if (baseUrl != null) {
url = new URL(baseUrl, "yourfilename.ext");
} else {
url = YourClass.class.getResource("yourfilename.ext");
}
} catch (MalformedURLException e) {
// Do something appropriate
}
これによりJava.net.URL
が得られ、Java.io.File
コンストラクターで使用できます。
たぶん、この方法は迅速な解決に使用できます。
public static String getResourcePath(String relativePath)
{
String pathStr = null;
URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
String codeLoaction = location.toString();
try{
if (codeLocation.endsWith(".jar"){
//Call from jar
Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
pathStr = path.toString();
}else{
//Call from IDE
pathStr = <Class>.class.getClassLoader().getResource(relativePath).getPath();
}
}catch(URISyntaxException ex){
ex.printStackTrace();
}
return pathStr;
}