相关文章推荐
兴奋的烤红薯  ·  ProcessBuilder ...·  1 年前    · 
慷慨的抽屉  ·  c# datetime to sql ...·  2 年前    · 
痴情的帽子  ·  c - Support of ASAN ...·  3 年前    · 

本文介绍java多种方式从classpath、url以及jar中读取文件。

我们仅使用java类实现一组测试示例,在测试类中,我们使用Hamcrest工具进行匹配验证。
测试类共享使用readFromInputStream方法,实现传输输入流至字符串,方便断言结果。

private String readFromInputStream(InputStream inputStream)
  throws IOException {
    StringBuilder resultStringBuilder = new StringBuilder();
    try (BufferedReader br
      = new BufferedReader(new InputStreamReader(inputStream))) {
        String line;
        while ((line = br.readLine()) != null) {
            resultStringBuilder.append(line).append("\n");
  return resultStringBuilder.toString();

当然,还有其他方式可以实现通用功能,你可以参考本系列其他文章。

从Classpath读取文件

本节解释如何从Classpath读文件,假设“fileTest.txt”在src/main/resources路径下:

@Test
public void givenFileNameAsAbsolutePath_whenUsingClasspath_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";
    Class clazz = FileOperationsTest.class;
    InputStream inputStream = clazz.getResourceAsStream("/fileTest.txt");
    String data = readFromInputStream(inputStream);
    Assert.assertThat(data, containsString(expectedData));

上面代码片段,我们使用当前类的getResourceAsStream 方法载入文件,并传递文件的绝对路径作为参数。我们也可以使用ClassLoader实例:

ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("fileTest.txt");
String data = readFromInputStream(inputStream);

我们获取当前类classLoader,通过使用getClass().getClassLoader()方法.两者的差异是当在ClassLoader实例上使用getResourceAsStream 方法,路径表示classpath的绝对路径。而通过类实例,路径是相对于包或通过反斜杠开头指明是绝对路径。

使用jdk7读文件

在jdk7中NIO包有很大的改进。让我们看一个示例,使用Files类和readAllBetes方法。readAllBetes方法接收Path参数,Path类被认为是 java.io.File的升级,并增加了额外的操作:

@Test
public void givenFilePath_whenUsingFilesReadAllBytes_thenFileData() {
   String expectedData = "Hello World from fileTest.txt!!!";
   Path path = Paths.get(getClass().getClassLoader()
     .getResource("fileTest.txt").toURI());       
   byte[] fileBytes = Files.readAllBytes(path);
   String data = new String(fileBytes);
   Assert.assertEquals(expectedData, data.trim());

jdk8读文件

jdk8中Files类的lines()方法,可以获取字符串流。下面通过示例读文件值字节,然后用utf-8编码生成字符。

@Test
public void givenFilePath_whenUsingFilesLines_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";
    Path path = Paths.get(getClass().getClassLoader()
      .getResource("fileTest.txt").toURI());
    StringBuilder data = new StringBuilder();
    Stream<String> lines = Files.lines(path);
    lines.forEach(line -> data.append(line).append("\n"));
    lines.close();
    Assert.assertEquals(expectedData, data.toString().trim());

使用io通道的Stream,如文件操作,我们需要使用close()显示地关闭流。

使用FileUtils读文件

另一个常用的方法是使用FileUtils类,需要增加依赖:

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.5</version>
</dependency>

可以应用最新的版本。

@Test
public void givenFileName_whenUsingFileUtils_thenFileData() {
    String expectedData = "Hello World from fileTest.txt!!!";
    ClassLoader classLoader = getClass().getClassLoader();
    File file = new File(classLoader.getResource("fileTest.txt").getFile());
    String data = FileUtils.readFileToString(file);
    Assert.assertEquals(expectedData, data.trim());

我们传递File对象给FileUtils类的方法readFileToString()。这个工具类负责加载内容,无需写任何模板代码,创建InputStream实例,读数据。

从url读数据

从url读内容,示例中我们使用“/”作为url:

@Test
public void givenURLName_whenUsingURL_thenFileData() {
    String expectedData = "Baeldung";
    URL urlObject = new URL("/");
    URLConnection urlConnection = urlObject.openConnection();
    InputStream inputStream = urlConnection.getInputStream();
    String data = readFromInputStream(inputStream);
    Assert.assertThat(data, containsString(expectedData));

除了使用标准sdk的URL和URLConnection类,还有其他方式可以实现。

从jar中读文件

从本地jar文件读文件内容,需jar中带有文件。示例中我们读取 “hamcrest-library-1.3.jar” 中“LICENSE.txt”文件:

@Test
public void givenFileName_whenUsingJarFile_thenFileData() {
    String expectedData = "BSD License";
    Class clazz = Matchers.class;
    InputStream inputStream = clazz.getResourceAsStream("/LICENSE.txt");
    String data = readFromInputStream(inputStream);
    Assert.assertThat(data, containsString(expectedData));

这里我们加载Hamcrest库中的LICENSE.txt文件,所以我们使用Matcher获取resource。同样也可以使用ClassLoader加载。

本文我们介绍了如何从不同位置读取文件,classpath,URL以及jar,并使用java核心api演示如何从文件中获取内容。

首先, 学习通过标准的的Java类,从classpath、URL或者Jar中加载文件。 然后,学习通用BufferedReader, Scanner, StreamTokenizer, DataInputStream, SequenceInputStream, FileChannel读取文件内容。也会讨论如何读取UTF-8编码的文件。 最后,学习Java7和Java8中新的加载和读取文件的技术。 2.1 输入文件 Scanner(Java 1.5) 按行读数据及String、Int类型等按分隔符读数据。 Files.lines, 返回Stream(Java 8) 流式数据处理,按行读取 Files.readAllLines, 返回List(Java 8) Files.readString, 读取String(Java 11), 文件最大 2G. Files.readAllBytes, 读取byte[](Java 7), 文件最大 2G. BufferedReader, 经典方式 (Java 1.1 -> f. 可以使用不同的方式逐行读取文件,下面我们来学习常见的几种方法。有时需要逐行读取文件为字符串。例如,通过将文件每一行读取为。类打开文件,然后逐行读取其内容。下面是逐行读取文件的。下面是一个简单的程序,显示了如何使用。是一个包含各种有用方法的实用程序类。方法可用于将所有文件行读入字符串。以读取模式打开文件,然后使用它的。到达文件末尾时,此方法返回。逐行读取文件内容的示例程序。 import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.io.Inpu... 不管你是新手还是老鸟,在程序中读取资源文件总会遇到一些找不到文件的问题,这与Java底层的实现有关,不能算bug,只要方法得当,问题还是可以解决的。项目的文件夹结构:repathtest ├─src │ └─com │ └─lavasoft │ ├─test │ └─res ├─doc1、在Ja... 1. ServletContext1. 调用getResourcesAsStream方法获取输入流, 相对于webroot, 不用加/2. 读取任何类型的文件3. *只能在web环境下使用InputStream in = this.getServletContext().getResourceAsStream("WEB-INF/classes/config/db.properties");2. 类... 一、为什么要读取配置信息 1、一般需要经常变动的文件信息,需要将他们放到配置文件中,这样做是为了在更改信息的时候比在java代码中改变方便。比如JDBC链接数据库的URL地址和用户名、密码。需要配置到配置文件中方便修改 二、如何读取配置文件中的信息 Class.getResourceAsStrea 1、一般工程中使用I/O类指定文件的绝对路径读取 FileInputStream fis = new FileInputStream("src/main/resources/zsm.properties"); ppt.load(fis); String memAddr1 = ppt.getProperty("memAddr1"); 2、Web工程中可以使用ServletCon...