我在JAR文件中有一个文件。例如,它是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;
答案 0 :(得分:47)
如果你的jar在类路径上:
InputStream is = YourClass.class.getResourceAsStream("1.txt");
如果它不在类路径上,那么您可以通过以下方式访问它:
URL url = new URL("jar:file:/absolute/location/of/yourJar.jar!/1.txt");
InputStream is = url.openStream();
答案 1 :(得分:28)
您无法使用File,因为此文件在文件系统上不是独立存在的。相反,你需要getResourceAsStream(),如下所示:
...
InputStream in = getClass().getResourceAsStream("/1.txt");
BufferedReader input = new BufferedReader(new InputStreamReader(in));
...
答案 2 :(得分:4)
您需要与this answer类似的东西。
您需要以特殊方式将文件从存档中拉出来。
BufferedReader input = new BufferedReader(new InputStreamReader(
this.getClass().getClassLoader().getResourceAsStream("1.txt")));
答案 3 :(得分:4)
Jar文件是一个zip文件.....
因此,要阅读jar文件,请尝试
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)
}
}
}
希望这有帮助。
答案 4 :(得分:2)
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")));
}
答案 5 :(得分:1)
之前我曾多次遇到同样的问题。 我希望在JDK 7中有人会写一个类路径文件系统,但还没有。
Spring有Resource类,它允许你很好地加载类路径资源。
答案非常好,但我想我可以添加到讨论中,展示一个适用于类路径资源的文件和目录的示例。
我写了一个小原型来解决这个问题。原型不处理每个边缘情况,但它确实处理在jar文件中的目录中寻找资源。
我已经使用Stack Overflow很长一段时间了。这是我第一次记得在回答一个问题时请原谅我,如果我长篇大论(这是我的本性)。
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();
}
}
}
}
}
答案 6 :(得分:1)
这有助于我将一个txt文件从jar文件复制到另一个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();
}
}
}
答案 7 :(得分:-1)
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);
}
}