JAR 파일에서 파일을 읽는 방법?
-
20-09-2019 - |
문제
항아리 파일에 파일이 있습니다. 이것의 1.txt
, 예를 들어.
어떻게 액세스 할 수 있습니까? 내 소스 코드는 다음과 같습니다.
Double result=0.0;
File file = new File("1.txt")); //how get this file from a jar file
BufferedReader input = new BufferedReader(new FileReader(file));
String line;
while ((line = input.readLine()) != null) {
if(me==Integer.parseInt(line.split(":")[0])){
result= parseDouble(line.split(":")[1]);
}
}
input.close();
return result;
해결책
이 파일은 파일 시스템에 독립적으로 존재하지 않기 때문에 파일을 사용할 수 없습니다. 대신 getResourceasstream ()이 필요합니다.
...
InputStream in = getClass().getResourceAsStream("/1.txt");
BufferedReader input = new BufferedReader(new InputStreamReader(in));
...
다른 팁
항아리가 클래스 경로에있는 경우 :
InputStream is = YourClass.class.getResourceAsStream("1.txt");
ClassPath에 있지 않으면 다음을 통해 액세스 할 수 있습니다.
URL url = new URL("jar:file:/absolute/location/of/yourJar.jar!/1.txt");
InputStream is = url.openStream();
비슷한 것 이 답변 당신이 필요로하는 것입니다.
그 특별한 방식으로 아카이브에서 파일을 꺼내야합니다.
BufferedReader input = new BufferedReader(new InputStreamReader(
this.getClass().getClassLoader().getResourceAsStream("1.txt")));
항아리 파일은 zip 파일입니다 .....
항아리 파일을 읽으려면 시도하십시오
ZipFile file = new ZipFile("whatever.jar");
if (file != null) {
ZipEntries entries = file.entries(); //get entries from the zip file...
if (entries != null) {
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
//use the entry to see if it's the file '1.txt'
//Read from the byte using file.getInputStream(entry)
}
}
}
도움이 되었기를 바랍니다.
private String loadResourceFileIntoString(String path) {
//path = "/resources/html/custom.css" for example
BufferedReader buffer = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(path)));
return buffer.lines().collect(Collectors.joining(System.getProperty("line.separator")));
}
나는이 같은 문제를 여러 번 전에 실행했습니다. 나는 JDK 7에서 누군가가 ClassPath 파일 시스템을 작성하기를 바랐지만 아직 아님.
Spring에는 ClassPath 리소스를 아주 잘로드 할 수있는 리소스 클래스가 있습니다.
답은 매우 좋았지 만 ClassPath 리소스 인 파일 및 디렉토리와 함께 작동하는 예제를 보여주는 토론에 추가 할 수 있다고 생각했습니다.
나는이 문제를 해결하기 위해 약간의 프로토 타입을 썼습니다. 프로토 타입은 모든 에지 케이스를 처리하지는 않지만 JAR 파일에있는 디렉토리에서 리소스를 찾는 것을 처리합니다.
나는 스택 오버플로를 꽤 언젠가 사용했습니다. 내가 질문에 대답 한 것을 기억 한 것은 이번이 처음이므로 오래 가면 용서하십시오 (내 본성입니다).
package com.foo;
import java.io.File;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.net.URL;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* Prototype resource reader.
* This prototype is devoid of error checking.
*
*
* I have two prototype jar files that I have setup.
* <pre>
* <dependency>
* <groupId>invoke</groupId>
* <artifactId>invoke</artifactId>
* <version>1.0-SNAPSHOT</version>
* </dependency>
*
* <dependency>
* <groupId>node</groupId>
* <artifactId>node</artifactId>
* <version>1.0-SNAPSHOT</version>
* </dependency>
* </pre>
* The jar files each have a file under /org/node/ called resource.txt.
* <br />
* This is just a prototype of what a handler would look like with classpath://
* I also have a resource.foo.txt in my local resources for this project.
* <br />
*/
public class ClasspathReader {
public static void main(String[] args) throws Exception {
/* This project includes two jar files that each have a resource located
in /org/node/ called resource.txt.
*/
/*
Name space is just a device I am using to see if a file in a dir
starts with a name space. Think of namespace like a file extension
but it is the start of the file not the end.
*/
String namespace = "resource";
//someResource is classpath.
String someResource = args.length > 0 ? args[0] :
//"classpath:///org/node/resource.txt"; It works with files
"classpath:///org/node/"; //It also works with directories
URI someResourceURI = URI.create(someResource);
System.out.println("URI of resource = " + someResourceURI);
someResource = someResourceURI.getPath();
System.out.println("PATH of resource =" + someResource);
boolean isDir = !someResource.endsWith(".txt");
/** Classpath resource can never really start with a starting slash.
* Logically they do, but in reality you have to strip it.
* This is a known behavior of classpath resources.
* It works with a slash unless the resource is in a jar file.
* Bottom line, by stripping it, it always works.
*/
if (someResource.startsWith("/")) {
someResource = someResource.substring(1);
}
/* Use the ClassLoader to lookup all resources that have this name.
Look for all resources that match the location we are looking for. */
Enumeration resources = null;
/* Check the context classloader first. Always use this if available. */
try {
resources =
Thread.currentThread().getContextClassLoader().getResources(someResource);
} catch (Exception ex) {
ex.printStackTrace();
}
if (resources == null || !resources.hasMoreElements()) {
resources = ClasspathReader.class.getClassLoader().getResources(someResource);
}
//Now iterate over the URLs of the resources from the classpath
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
/* if the resource is a file, it just means that we can use normal mechanism
to scan the directory.
*/
if (resource.getProtocol().equals("file")) {
//if it is a file then we can handle it the normal way.
handleFile(resource, namespace);
continue;
}
System.out.println("Resource " + resource);
/*
Split up the string that looks like this:
jar:file:/Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar!/org/node/
into
this /Users/rick/.m2/repository/invoke/invoke/1.0-SNAPSHOT/invoke-1.0-SNAPSHOT.jar
and this
/org/node/
*/
String[] split = resource.toString().split(":");
String[] split2 = split[2].split("!");
String zipFileName = split2[0];
String sresource = split2[1];
System.out.printf("After split zip file name = %s," +
" \nresource in zip %s \n", zipFileName, sresource);
/* Open up the zip file. */
ZipFile zipFile = new ZipFile(zipFileName);
/* Iterate through the entries. */
Enumeration entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
/* If it is a directory, then skip it. */
if (entry.isDirectory()) {
continue;
}
String entryName = entry.getName();
System.out.printf("zip entry name %s \n", entryName);
/* If it does not start with our someResource String
then it is not our resource so continue.
*/
if (!entryName.startsWith(someResource)) {
continue;
}
/* the fileName part from the entry name.
* where /foo/bar/foo/bee/bar.txt, bar.txt is the file
*/
String fileName = entryName.substring(entryName.lastIndexOf("/") + 1);
System.out.printf("fileName %s \n", fileName);
/* See if the file starts with our namespace and ends with our extension.
*/
if (fileName.startsWith(namespace) && fileName.endsWith(".txt")) {
/* If you found the file, print out
the contents fo the file to System.out.*/
try (Reader reader = new InputStreamReader(zipFile.getInputStream(entry))) {
StringBuilder builder = new StringBuilder();
int ch = 0;
while ((ch = reader.read()) != -1) {
builder.append((char) ch);
}
System.out.printf("zip fileName = %s\n\n####\n contents of file %s\n###\n", entryName, builder);
} catch (Exception ex) {
ex.printStackTrace();
}
}
//use the entry to see if it's the file '1.txt'
//Read from the byte using file.getInputStream(entry)
}
}
}
/**
* The file was on the file system not a zip file,
* this is here for completeness for this example.
* otherwise.
*
* @param resource
* @param namespace
* @throws Exception
*/
private static void handleFile(URL resource, String namespace) throws Exception {
System.out.println("Handle this resource as a file " + resource);
URI uri = resource.toURI();
File file = new File(uri.getPath());
if (file.isDirectory()) {
for (File childFile : file.listFiles()) {
if (childFile.isDirectory()) {
continue;
}
String fileName = childFile.getName();
if (fileName.startsWith(namespace) && fileName.endsWith("txt")) {
try (FileReader reader = new FileReader(childFile)) {
StringBuilder builder = new StringBuilder();
int ch = 0;
while ((ch = reader.read()) != -1) {
builder.append((char) ch);
}
System.out.printf("fileName = %s\n\n####\n contents of file %s\n###\n", childFile, builder);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
} else {
String fileName = file.getName();
if (fileName.startsWith(namespace) && fileName.endsWith("txt")) {
try (FileReader reader = new FileReader(file)) {
StringBuilder builder = new StringBuilder();
int ch = 0;
while ((ch = reader.read()) != -1) {
builder.append((char) ch);
}
System.out.printf("fileName = %s\n\n####\n contents of file %s\n###\n", fileName, builder);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}
}
이것은 JAR 파일에서 다른 txt 파일로 txt 파일을 복사하는 데 효과적이었습니다.
public static void copyTextMethod() throws Exception{
String inputPath = "path/to/.jar";
String outputPath = "Desktop/CopyText.txt";
File resStreamOut = new File(outputPath);
int readBytes;
JarFile file = new JarFile(inputPath);
FileWriter fw = new FileWriter(resStreamOut);
try{
Enumeration<JarEntry> entries = file.entries();
while (entries.hasMoreElements()){
JarEntry entry = entries.nextElement();
if (entry.getName().equals("readMe/tempReadme.txt")) {
System.out.println(entry +" : Entry");
InputStream is = file.getInputStream(entry);
BufferedWriter output = new BufferedWriter(fw);
while ((readBytes = is.read()) != -1) {
output.write((char) readBytes);
}
System.out.println(outputPath);
output.close();
}
}
} catch(Exception er){
er.printStackTrace();
}
}
}
InputStream inputStreamLastName = this.getClass().getClassLoader().getResourceAsStream("path of file");
try {
br = new BufferedReader(new InputStreamReader(inputStreamLastName, "UTF-8"));
String sCurrentLine;
ArrayList<String> lastNamesList = new ArrayList<String>();
while ((sCurrentLine = br.readLine()) != null) {
if(sCurrentLine.length()>=min && sCurrentLine.length()<=max){
lastNamesList.add(sCurrentLine);
}
}