Skip to main content
 首页 » 编程设计

多种方式实现java读取文件

2022年07月19日139bonelee

多种方式实现java读取文件

本文介绍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演示如何从文件中获取内容。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/79601499
阅读延展