내 jar File에서 리소스 폴더의 폴더에 액세스하는 방법
프로젝트의 루트에 리소스 폴더/패키지가 있으며 특정 파일을 로드하지 않으려는 경우특정 파일을 로드하려면 class.getResourceAsStream을 사용하고 나는 괜찮을 것이다!!내가 실제로 하고 싶은 것은 자원 폴더 안에 "폴더"를 로드하고, 그 폴더 안에 있는 파일들을 반복해서 각 파일에 스트림을 가져와 내용에서 읽는 것이다.런타임 전에 파일 이름이 결정되지 않았다고 가정하십시오...어떻게 해야 하나?당신의 jar File에 있는 Folder에 있는 파일 목록을 얻을 수 있는 방법이 있는가?리소스가 있는 Jar 파일이 코드가 실행 중인 jar 파일과 동일하다는 점에 유의하십시오...
마침내 해결책을 찾았다:
final String path = "sample/folder";
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
if(jarFile.isFile()) { // Run with JAR file
final JarFile jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(path + "/")) { //filter according to the path
System.out.println(name);
}
}
jar.close();
} else { // Run with IDE
final URL url = Launcher.class.getResource("/" + path);
if (url != null) {
try {
final File apps = new File(url.toURI());
for (File app : apps.listFiles()) {
System.out.println(app);
}
} catch (URISyntaxException ex) {
// never happens
}
}
}
두 번째 블록은 (항아리 파일이 아닌) IDE에서 응용 프로그램을 실행할 때에만 작동하며, 마음에 들지 않으면 제거할 수 있다.
다음을 시도해 보십시오.
리소스 경로 만들기"<PathRelativeToThisClassFile>/<ResourceDirectory>"
예: 클래스 경로가 com.abc.package인 경우.MyClass 및 리소스 파일은 src/com/abc/package/resource/:
URL url = MyClass.class.getResource("resources/");
if (url == null) {
// error - missing folder
} else {
File dir = new File(url.toURI());
for (File nextFile : dir.listFiles()) {
// Do something with nextFile
}
}
사용할 수도 있다.
URL url = MyClass.class.getResource("/com/abc/package/resources/");
나는 이것이 오래전 일이라는 것을 안다. 그러나 단지 다른 사람들을 위해 이 주제를 접하게 된다.당신이 할 수 있는 일은getResourceAsStream()
디렉토리 경로 및 입력 스트림이 해당 dir의 모든 파일 이름을 가지는 방법.그런 다음 dir 경로를 각 파일 이름으로 연결하고 루프에 있는 각 파일에 대해 getResourceAsStream을 호출하십시오.
항아리에 들어 있는 리소스에서 하둡 구성을 로드하는 동안에도 동일한 문제가 발생했었습니다...IDE 및 병(해제 버전)에 모두 적용.
찾았다java.nio.file.DirectoryStream
로컬 파일 시스템과 병 모두에 대해 디렉터리 내용을 반복하는 데 최선을 다하십시오.
String fooFolder = "/foo/folder";
....
ClassLoader classLoader = foofClass.class.getClassLoader();
try {
uri = classLoader.getResource(fooFolder).toURI();
} catch (URISyntaxException e) {
throw new FooException(e.getMessage());
} catch (NullPointerException e){
throw new FooException(e.getMessage());
}
if(uri == null){
throw new FooException("something is wrong directory or files missing");
}
/** i want to know if i am inside the jar or working on the IDE*/
if(uri.getScheme().contains("jar")){
/** jar case */
try{
URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation();
//jar.toString() begins with file:
//i want to trim it out...
Path jarFile = Paths.get(jar.toString().substring("file:".length()));
FileSystem fs = FileSystems.newFileSystem(jarFile, null);
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder));
for(Path p: directoryStream){
InputStream is = FooClass.class.getResourceAsStream(p.toString()) ;
performFooOverInputStream(is);
/** your logic here **/
}
}catch(IOException e) {
throw new FooException(e.getMessage());
}
}
else{
/** IDE case */
Path path = Paths.get(uri);
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
for(Path p : directoryStream){
InputStream is = new FileInputStream(p.toFile());
performFooOverInputStream(is);
}
} catch (IOException _e) {
throw new FooException(_e.getMessage());
}
}
다음 코드는 원하는 "폴더"가 항아리 안에 있는지 여부에 관계없이 Path로 반환한다.
private Path getFolderPath() throws URISyntaxException, IOException {
URI uri = getClass().getClassLoader().getResource("folder").toURI();
if ("jar".equals(uri.getScheme())) {
FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
return fileSystem.getPath("path/to/folder/inside/jar");
} else {
return Paths.get(uri);
}
}
자바 7+ 필요.
다른 솔루션, 다음 작업을 수행할 수 있음ResourceLoader
다음과 같은 경우:
import org.springframework.core.io.Resource;
import org.apache.commons.io.FileUtils;
@Autowire
private ResourceLoader resourceLoader;
...
Resource resource = resourceLoader.getResource("classpath:/path/to/you/dir");
File file = resource.getFile();
Iterator<File> fi = FileUtils.iterateFiles(file, null, true);
while(fi.hasNext()) {
load(fi.next())
}
다른 답들이 지적하듯이 일단 자원이 항아리 파일 안에 들어가면 상황은 정말 추악해진다.우리의 경우, 이 해결책은 다음과 같다.
https://stackoverflow.com/a/13227570/516188
테스트에서는 매우 잘 작동하지만(테스트 실행 시 코드는 jar 파일로 포장되지 않기 때문에), 앱이 실제로 정상적으로 실행될 때는 작동하지 않는다.그래서 내가 한 일은...앱에 있는 파일 리스트를 하드코드로 작성하지만, 디스크에서 실제 리스트를 읽어내는 테스트(테스트에서 작동하기 때문에 할 수 있음)가 있는데, 실제 리스트가 앱이 반환하는 리스트와 일치하지 않으면 실패한다.
그래야 내 앱에 간단한 코드(노 트릭)가 있고, 시험 덕분에 목록에 새 항목을 추가하는 것을 잊지 않았을 것이다.
아래 코드는 사용자 정의 리소스 디렉터리에서 .yaml 파일을 가져온다.
ClassLoader classLoader = this.getClass().getClassLoader();
URI uri = classLoader.getResource(directoryPath).toURI();
if("jar".equalsIgnoreCase(uri.getScheme())){
Pattern pattern = Pattern.compile("^.+" +"/classes/" + directoryPath + "/.+.yaml$");
log.debug("pattern {} ", pattern.pattern());
ApplicationHome home = new ApplicationHome(SomeApplication.class);
JarFile file = new JarFile(home.getSource());
Enumeration<JarEntry> jarEntries = file.entries() ;
while(jarEntries.hasMoreElements()){
JarEntry entry = jarEntries.nextElement();
Matcher matcher = pattern.matcher(entry.getName());
if(matcher.find()){
InputStream in =
file.getInputStream(entry);
//work on the stream
}
}
}else{
//When Spring boot application executed through Non-Jar strategy like through IDE or as a War.
String path = uri.getPath();
File[] files = new File(path).listFiles();
for(File file: files){
if(file != null){
try {
InputStream is = new FileInputStream(file);
//work on stream
} catch (Exception e) {
log.error("Exception while parsing file yaml file {} : {} " , file.getAbsolutePath(), e.getMessage());
}
}else{
log.warn("File Object is null while parsing yaml file");
}
}
}
만약 당신이 Spring을 사용하고 있다면 당신은 사용할 수 있다.org.springframework.core.io.support.PathMatchingResourcePatternResolver
그리고 처리하다Resource
파일보다는 객체.이것은 Jar 파일 안과 밖에서 실행할 때 작동한다.
PathMatchingResourcePatternResolver r = new PathMatchingResourcePatternResolver();
Resource[] resources = r.getResources("/myfolder/*");
그런 다음 다음을 사용하여 데이터에 액세스할 수 있다.getInputStream
및 의 파일 이름getFilename
.
다음 항목을 사용하려고 해도 실패한다는 점에 유의하십시오.getFile
항아리에서 도망치다가
내 항아리 파일 안에는 업로드라는 폴더가 있었고, 이 폴더에는 세 개의 다른 텍스트 파일이 들어 있었다. 항아리 파일 외부에 정확히 동일한 폴더와 파일이 있어야 했다. 나는 아래 코드를 사용했다.
URL inputUrl = getClass().getResource("/upload/blabla1.txt");
File dest1 = new File("upload/blabla1.txt");
FileUtils.copyURLToFile(inputUrl, dest1);
URL inputUrl2 = getClass().getResource("/upload/blabla2.txt");
File dest2 = new File("upload/blabla2.txt");
FileUtils.copyURLToFile(inputUrl2, dest2);
URL inputUrl3 = getClass().getResource("/upload/blabla3.txt");
File dest3 = new File("upload/Bblabla3.txt");
FileUtils.copyURLToFile(inputUrl3, dest3);
단순함...OSGi를 사용하다.OSGi에서는 findEntries 및 findPaths로 번들 항목을 반복할 수 있다.
이 링크는 방법을 알려준다.
마법은 getResourceAsStream() 메서드:
InputStream is =
this.getClass().getClassLoader().getResourceAsStream("yourpackage/mypackage/myfile.xml")
'programing' 카테고리의 다른 글
Apache에서 vue 기록이 있는 https 강제 적용 (0) | 2022.05.04 |
---|---|
vuexfire로 쿼리하는 방법 (0) | 2022.05.04 |
vuejs에서 기본 페이지 지정을 편집하시겠습니까? (0) | 2022.05.04 |
모든 구성 요소에서 변수를 사용할 수 있도록 하는 Vue (0) | 2022.05.04 |
클랭을 감지하는 데 사용할 수 있는 미리 정의된 매크로 (0) | 2022.05.04 |