나는 자원의 길을 찾으려고 노력하고 있지만 운이 없었다.
이것은 작동하지만 (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의 디렉토리가 아닌 경우가 많으며, 특히 JAR (또는 해당 프로그램)이 Windows의 시작 메뉴에서 실행되는 경우에 특히 그렇습니다. 그래서 여기 내가 한 일이 있으며 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
디렉토리 (maven 스타일) 아래의 foo.jar에있는 파일 (myfile.txt)이있는 경우 . 당신은 그것을 다음과 같이 언급 할 것입니다 :
src/main/resources/myfile.txt
jar 파일을 사용하여 덤프 jar -tvf myjar.jar
하면 jar 파일 내의 출력과 상대 경로가 표시되고 FORWARD SLASHES가 사용됩니다.
답변
필자의 경우 경로 대신 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을 사용하여 컨텐츠에 액세스 할 수 있습니다.