我正在尝试读取在 CLASSPATH 系统变量中设置的文本文件。不是用户变量。
我正在尝试获取文件的输入流,如下所示:
将文件 (D:\myDir
) 的目录放在 CLASSPATH 中,然后尝试以下操作:
InputStream in = this.getClass().getClassLoader().getResourceAsStream("SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("/SomeTextFile.txt");
InputStream in = this.getClass().getClassLoader().getResourceAsStream("//SomeTextFile.txt");
将文件 (D:\myDir\SomeTextFile.txt
) 的完整路径放在 CLASSPATH 中,然后尝试上面的 3 行代码。
但不幸的是,它们都没有工作,我总是将 null
放入我的 InputStream in
。
使用类路径上的目录,从同一个类加载器加载的类中,您应该能够使用以下任一:
// From ClassLoader, all paths are "absolute" already - there's no context
// from which they could be relative. Therefore you don't need a leading slash.
InputStream in = this.getClass().getClassLoader()
.getResourceAsStream("SomeTextFile.txt");
// From Class, the path is relative to the package of the class unless
// you include a leading slash, so if you don't want to use the current
// package, include a slash like this:
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
如果这些都不起作用,则表明还有其他问题。
因此,例如,使用以下代码:
package dummy;
import java.io.*;
public class Test
{
public static void main(String[] args)
{
InputStream stream = Test.class.getResourceAsStream("/SomeTextFile.txt");
System.out.println(stream != null);
stream = Test.class.getClassLoader().getResourceAsStream("SomeTextFile.txt");
System.out.println(stream != null);
}
}
而这个目录结构:
code
dummy
Test.class
txt
SomeTextFile.txt
然后(在 Linux 机器上使用 Unix 路径分隔符):
java -classpath code:txt dummy.Test
结果:
true
true
使用 Spring 框架(作为实用程序集合或容器 - 您不需要使用后一个功能)时,您可以轻松使用 Resource 抽象。
Resource resource = new ClassPathResource("com/example/Foo.class");
通过 Resource 接口,您可以通过 InputStream、URL、URI 或 File 访问资源。将资源类型更改为例如文件系统资源是更改实例的简单问题。
这就是我使用 Java 7 NIO 在类路径上读取文本文件所有行的方式:
...
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
...
Files.readAllLines(
Paths.get(this.getClass().getResource("res.txt").toURI()), Charset.defaultCharset());
注意,这是如何完成的示例。您必须根据需要进行改进。此示例仅在文件实际存在于您的类路径中时才有效,否则当 getResource() 返回 null 并在其上调用 .toURI() 时将引发 NullPointerException。
此外,从 Java 7 开始,指定字符集的一种方便方法是使用 java.nio.charset.StandardCharsets
中定义的常量(根据它们的 javadocs,这些常量“保证在 Java 平台的每个实现上都可用。”)。
因此,如果您知道文件的编码为 UTF-8,则明确指定字符集 StandardCharsets.UTF_8
Spring
的 StreamUtils.copyToString
之类的东西。
请试试
InputStream in = this.getClass().getResourceAsStream("/SomeTextFile.txt");
您的尝试不起作用,因为只有您的类的类加载器才能从类路径加载。您为 java 系统本身使用了类加载器。
要实际读取文件的内容,我喜欢使用 Commons IO + Spring Core。假设 Java 8:
try (InputStream stream = new ClassPathResource("package/resource").getInputStream()) {
IOUtils.toString(stream);
}
或者:
InputStream stream = null;
try {
stream = new ClassPathResource("/log4j.xml").getInputStream();
IOUtils.toString(stream);
} finally {
IOUtils.closeQuietly(stream);
}
要获取类绝对路径,请尝试以下操作:
String url = this.getClass().getResource("").getPath();
不知何故,最好的答案对我不起作用。我需要使用稍微不同的代码。
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("SomeTextFile.txt");
我希望这对那些遇到同样问题的人有所帮助。
如果你使用番石榴:
import com.google.common.io.Resources;
我们可以从 CLASSPATH 中获取 URL:
URL resource = Resources.getResource("test.txt");
String file = resource.getFile(); // get file path
或输入流:
InputStream is = Resources.getResource("test.txt").openStream();
Ways to convert an InputStream to a String
recources
下的子图中的图像。使用我的相对文件路径在本地工作,但 Resources.getResource("submap/file").openStream()
是我在远程服务器上部署时得到的唯一解决方案
要将文件的内容从 classpath
读入字符串,您可以使用以下命令:
private String resourceToString(String filePath) throws IOException, URISyntaxException
{
try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(filePath))
{
return IOUtils.toString(inputStream);
}
}
注意:
IOUtils
是 Commons IO
的一部分。
像这样称呼它:
String fileContents = resourceToString("ImOnTheClasspath.txt");
您说“我正在尝试读取在 CLASSPATH 系统变量中设置的文本文件。”我猜这是在 Windows 上,您正在使用这个丑陋的对话框来编辑“系统变量”。
现在您在控制台中运行您的 Java 程序。这不起作用:控制台在启动时会获取系统变量值的副本。这意味着之后对话框中的任何更改都不会产生任何影响。
有这些解决方案:
每次更改后启动一个新控制台 在控制台中使用 set CLASSPATH=... 在控制台中设置变量的副本,当您的代码工作时,将最后一个值粘贴到变量对话框中。将对 Java 的调用放入 .BAT 文件并双击它。这将每次创建一个新控制台(从而复制系统变量的当前值)。
注意:如果您还有一个用户变量 CLASSPATH
,那么它会影响您的系统变量。这就是为什么最好将 Java 程序的调用放入 .BAT
文件并在其中设置类路径(使用 set CLASSPATH=
)而不是依赖全局系统或用户变量。
这也确保您可以在您的计算机上运行多个 Java 程序,因为它们必然具有不同的类路径。
我的回答与问题中所问的不完全一样。相反,我给出了一个解决方案,我们可以多么容易地从我们的项目类路径中将文件读入 Java 应用程序。
例如,假设配置文件名 example.xml 位于如下路径中:-
com.myproject.config.dev
我们的 java 可执行类文件位于以下路径中:-
com.myproject.server.main
现在只需检查上述路径,这是最近的公共目录/文件夹,您可以从中访问 dev 和主目录/文件夹(com.myproject.server.main - 我们的应用程序的 java 可执行类所在的位置) - 我们可以看到它是 myproject 文件夹/目录,它是我们可以访问 example.xml 文件的最近的公共目录/文件夹。因此,从位于文件夹/目录 main 中的 java 可执行类中,我们必须返回两个步骤,如 ../../ 来访问 myproject。现在按照这个,看看我们如何读取文件:-
package com.myproject.server.main;
class Example {
File xmlFile;
public Example(){
String filePath = this.getClass().getResource("../../config/dev/example.xml").getPath();
this.xmlFile = new File(filePath);
}
public File getXMLFile() {
return this.xmlFile;
}
public static void main(String args[]){
Example ex = new Example();
File xmlFile = ex.getXMLFile();
}
}
如果您在 jar 文件中编译您的项目:您可以将文件放在 resources/files/your_file.text 或 pdf 中;
并使用此代码:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
public class readFileService(){
private static final Logger LOGGER = LoggerFactory.getLogger(readFileService.class);
public byte[] getFile(){
String filePath="/files/your_file";
InputStream inputStreamFile;
byte[] bytes;
try{
inputStreamFile = this.getClass().getResourceAsStream(filePath);
bytes = new byte[inputStreamFile.available()];
inputStreamFile.read(bytes);
} catch(NullPointerException | IOException e) {
LOGGER.error("Erreur read file "+filePath+" error message :" +e.getMessage());
return null;
}
return bytes;
}
}
我正在使用 webshpere 应用程序服务器,我的 Web 模块是基于 Spring MVC 构建的。 Test.properties
位于资源文件夹中,我尝试使用以下内容加载此文件:
this.getClass().getClassLoader().getResourceAsStream("Test.properties"); this.getClass().getResourceAsStream("/Test.properties");
上述代码均未加载文件。
但在以下代码的帮助下,属性文件已成功加载:
Thread.currentThread().getContextClassLoader().getResourceAsStream("Test.properties");
感谢用户“user1695166”。
使用org.apache.commons.io.FileUtils.readFileToString(new File("src/test/resources/sample-data/fileName.txt"));
不要使用 getClassLoader() 方法并在文件名前使用“/”。 “/“ 非常重要
this.getClass().getResourceAsStream("/SomeTextFile.txt");
/
与使用 getClassLoader()
方法的效果完全相同。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile
{
/**
* * feel free to make any modification I have have been here so I feel you
* * * @param args * @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// thread pool of 10
File dir = new File(".");
// read file from same directory as source //
if (dir.isDirectory()) {
File[] files = dir.listFiles();
for (File file : files) {
// if you wanna read file name with txt files
if (file.getName().contains("txt")) {
System.out.println(file.getName());
}
// if you want to open text file and read each line then
if (file.getName().contains("txt")) {
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(
file.getAbsolutePath());
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(
fileReader);
String line;
// get file details and get info you need.
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
// here you can say...
// System.out.println(line.substring(0, 10)); this
// prints from 0 to 10 indext
}
} catch (FileNotFoundException ex) {
System.out.println("Unable to open file '"
+ file.getName() + "'");
} catch (IOException ex) {
System.out.println("Error reading file '"
+ file.getName() + "'");
// Or we could just do this:
ex.printStackTrace();
}
}
}
}
}
}
你必须把你的“系统变量”放在java类路径上。
getResourceAsStream()
的类的包File.Separator
- 因为您不是在请求 file,而是在请求 resource。重要的是要了解所涉及的抽象不是文件系统。Class.getResourceAsStream
确实是调用ClassLoader.getResourceAsStream
的便捷方法,但具有“相对”资源的附加功能。如果你指定一个绝对资源,那么任何使用同一个类加载器的调用都会做同样的事情。