1.概述

在这篇文章里, 我们将探索不同的方式从文件中读取数据。

首先, 学习通过标准的的Java类,从classpathURL或者Jar中加载文件。

然后,学习通用BufferedReader, Scanner, StreamTokenizer, DataInputStream, SequenceInputStream, FileChannel读取文件内容。也会讨论如何读取UTF-8编码的文件。

最后,学习Java7和Java8中新的加载和读取文件的技术。

2.准备

2.1 输入文件

这篇文章的很多示例,从名为fileTest.txt的文件读取文本内容,文件包含

Hello,World!

有少量示例, 我们会读取不同的文件, 示例中会有说明。

2.2 辅助方法

很多示例都会用到共用的方法readFromInputStream, 该方法将InputStream转化String

    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();}

3.从Classpath读取文件

3.1 使用标准Java

src/main/resources读取文件fileTest.txt

    @Testpublic void test() throws IOException {String expectedData = "Hello,World!";Class<ReadFileTest> clazz = ReadFileTest.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);

这两种方法的主要区别是, 当前类的ClassLoadergetResourceAsStream方法,入参路径是从classpath开始。

而类实例的入参是相对于包路径,但路径开始使用'/'符号, 也是绝对路径。

特别要注意的是, 文件打开读取完数据后, 始终需要关闭

inputStream.close();

3.2 使用commons-io库

另一个比较常用的方法是使用commons-io包里的FileUtils.readFileToString方法。

        <dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>1.4</version></dependency>
    @Testpublic void useCommonIO() throws IOException {String expectedData = "Hello,World!";ClassLoader classLoader = getClass().getClassLoader();File file = new File(classLoader.getResource("fileTest.txt").getFile());String data = FileUtils.readFileToString(file, "UTF-8");assertEquals(expectedData, data.trim());}

该方法入参是File对象。这个工具类的优点是不用编码InputStream实例的相关代码。
这个库还提供了IOUtils类。

    @Testpublic void useCommonIO2() throws IOException {String expectedData = "Hello,World!";FileInputStream fis = new FileInputStream("src/test/resources/fileTest.txt");String data = IOUtils.toString(fis, "UTF-8");assertEquals(expectedData, data.trim());}

4.BufferedReader

@Test
public void bufferedReader() throws IOException {String expected_value = "Hello,World!";String file ="src/test/resources/fileTest.txt";BufferedReader reader = new BufferedReader(new FileReader(file));String currentLine = reader.readLine();reader.close();assertEquals(expected_value, currentLine);
}

当读取结束的时候, reader.readLine()会返回null

5.Java NIO

NIO是在JDK7中添加。

5.1读取小文件

首先看一下关于Files.readAllLines的示例

    @Testpublic void readSmallFile()  throws IOException {String expected_value = "Hello,World!";Path path = Paths.get("src/test/resources/fileTest.txt");String read = Files.readAllLines(path).get(0);assertEquals(expected_value, read);}

入参Path对象,Path可以认为是java.io.File的升级版本,提供一些额外的功能。

如果读取的是二进制文件,可以使用Files.readAllBytes()方法

5.2读取大文件

如果想要读取大文件, 我们可以使用Files类和BufferedReader类。

    @Testpublic void readLargeFile() throws IOException {String expected_value = "Hello,World!";Path path = Paths.get("src/test/resources/fileTest.txt");BufferedReader reader = Files.newBufferedReader(path);String line = reader.readLine();assertEquals(expected_value, line);}

5.3Files.lines

在JDK8中,Files类增加了lines方法,这个方法将返回Stream<String>。跟文件操作一样,Stream需要显式调用的close()。Files API提供了很多简单读取文件的方法。

6.Scanner

下面我们将使用Scanner读取文件,使用逗号(,)作为定界符(delimiter)。

@Test
public void whenReadWithScanner_thenCorrect()throws IOException {String file = "src/test/resources/fileTest.txt";Scanner scanner = new Scanner(new File(file));scanner.useDelimiter(",");assertTrue(scanner.hasNext());assertEquals("Hello", scanner.next());assertEquals("World!", scanner.next());scanner.close();
}

Scanner默认的定界符是空格。它适用于从控制台读取输入或者内容有固定定界符的内容时。

7.StreamTokenizer

tokenizer会指出下一个token的类型,String或Number。

tokenizer.nval - 如果类型为Number时,读取该字段

tokenizer.sval - 如果类型为String时,读取该字段

@Test
public void readWithTokenize()throws IOException {String file = "src/test/resources/fileTestTokenizer.txt";FileReader reader = new FileReader(file);StreamTokenizer tokenizer = new StreamTokenizer(reader);//  1tokenizer.nextToken();assertEquals(StreamTokenizer.TT_WORD, tokenizer.ttype);assertEquals("Hello", tokenizer.sval);//  2tokenizer.nextToken();assertEquals(StreamTokenizer.TT_NUMBER, tokenizer.ttype);assertEquals(1, tokenizer.nval, 0.0000001);//  3tokenizer.nextToken();assertEquals(StreamTokenizer.TT_EOF, tokenizer.ttype);reader.close();
}

8.DataInputStream

如果要读取二进制文件或者原生数据,可以使用DataInputStream

@Test
public void whenReadWithDataInputStream() throws IOException {String expectedValue = "Hello,World!";String file ="src/test/resources/fileTest.txt";String result = null;DataInputStream reader = new DataInputStream(new FileInputStream(file));int nBytesToRead = reader.available();if(nBytesToRead > 0) {byte[] bytes = new byte[nBytesToRead];reader.read(bytes);result = new String(bytes);}assertEquals(expectedValue, result);
}

9.FileChannel

如果读取的是一个大文件,FileChannel速度会超过standard IO。

@Test
public void whenReadWithFileChannel()throws IOException {String expected_value = "Hello,World!";String file = "src/test/resources/fileTest.txt";RandomAccessFile reader = new RandomAccessFile(file, "r");FileChannel channel = reader.getChannel();int bufferSize = 1024;if (bufferSize > channel.size()) {bufferSize = (int) channel.size();}ByteBuffer buff = ByteBuffer.allocate(bufferSize);channel.read(buff);buff.flip();assertEquals(expected_value, new String(buff.array()));channel.close();reader.close();
}

10.读取utf-8编码的文件

@Test
public void whenReadUTFEncodedFile()throws IOException {String expected_value = "你好,世界!";String file = "src/test/resources/fileTestUtf8.txt";BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));String currentLine = reader.readLine();reader.close();assertEquals(expected_value, currentLine);
}

11.从URL读取数据

@Test
public void readFromURL() throws IOException {URL urlObject = new URL("https://www.baidu.com");URLConnection urlConnection = urlObject.openConnection();InputStream inputStream = urlConnection.getInputStream();String data = readFromInputStream(inputStream);
}

12.从jar包中读取文件

我们的目标是读取junit-4.12.jar包中的LICENSE-junit.txt文件。clazz只需要这个Jar中的类就行。

@Test
public void readFromJar() throws IOException {String expectedData = "Eclipse Public License";Class clazz = Test.class;InputStream inputStream = clazz.getResourceAsStream("/LICENSE-junit.txt");String data = readFromInputStream(inputStream);Assert.assertThat(data, containsString(expectedData));
}

Java读取文件的N种方法相关推荐

  1. 用Java读取文件的5种方法-BufferedReader,FileInputStream,文件,扫描仪,RandomAccessFile

    There are many different ways to read a file in Java. In this tutorial, we will look into 5 differen ...

  2. java遍历文件和归类_java读取文件的两种方法:java.io和java.lang.ClassLoader

    java读取文件的两种方法:java.io和java.lang.ClassLoader 什么时候使用java.io,什么时候使用java.lang.ClassLoader呢? (注:要是之前读xml文 ...

  3. php读取文件内容5种方法

    实际应用当中,请注意关闭 fclose($fp); php读取文件内容: -–第一种方法-–fread()--– <?php$file_path= "test.txt";if ...

  4. 81. read readline readlines 读取文件的三种方法

    81. read readline readlines 读取文件的三种方法 文章目录 81. read readline readlines 读取文件的三种方法 1. 读取文件的三种方法 2. rea ...

  5. java写入文件不覆盖写入_Java写入文件–用Java写入文件的4种方法

    java写入文件不覆盖写入 Java provides several ways to write to file. We can use FileWriter, BufferedWriter, ja ...

  6. java文件写入不覆盖_java写入文件不覆盖写入_Java写入文件–用Java写入文件的4种方法...

    java写入文件不覆盖写入 Java provides several ways to write to file. We can use FileWriter, BufferedWriter, ja ...

  7. Java读取文件内容的六种方法

    1.Scanner 第一种方式是Scanner,从JDK1.5开始提供的API,特点是可以按行读取.按分割符去读取文件数据,既可以读取String类型,也可以读取Int类型.Long类型等基础数据类型 ...

  8. python中几种读取文件的方法_python 逐行读取文件的几种方法

    Python四种逐行读取文件内容的方法 下面四种Python逐行读取文件内容的方法, 分析了各种方法的优缺点及应用场景,以下代码在python3中测试通过, python2中运行部分代码已注释,稍加修 ...

  9. python读取文件多行内容-python 逐行读取文件的几种方法

    Python四种逐行读取文件内容的方法 下面四种Python逐行读取文件内容的方法, 分析了各种方法的优缺点及应用场景,以下代码在python3中测试通过, python2中运行部分代码已注释,稍加修 ...

  10. Shell按行读取文件的3种方法

    Shell按行读取文件的方法有很多,常见的三种方法如下: 要读取的文件: 1 [root@mini05 20180930-2]# cat file.info 2 111 3 222 4 333 444 ...

最新文章

  1. Building and running Node.js for Android
  2. 进程在与Windows Process Activation Service通信时出现严重错误 w3wp.exe错误
  3. Win 驱动编程 - 内核里操作注册表
  4. 30段极简Python代码:这些小技巧你都Get了么?
  5. 润乾报表列太多导致渲染速度慢_报表自动化: 如何选择可视化大屏开发利器
  6. highCharts文档与演示效果的使用 - 文档(应用型)解读
  7. SQL语句优化常见方法
  8. 犀牛软件rhinoceros的参数化设计插件草蜢grasshopper的安装
  9. 【雕爷学编程】Arduino动手做(84)---DS1307时钟模块
  10. Redis3.x 源码安装
  11. 程序员课外拓展004:Photoshop CC 2018详细图文安装教程
  12. html中文字放在图片下边,css图片下边怎么加字
  13. dede所有目录模板全解
  14. 解决xshell中数字小键盘不能使用的问题
  15. 什么是大数据与智能数据?什么是惯性测量单元与GNSS?
  16. 熟悉Hive 实验2
  17. java中什么是结果集,Java中对数据库查询结果集进行操作的对象是()
  18. 你们要的Java学习路线图,来喽
  19. MATLAB中对矩阵的变换
  20. WIN10 怎么关闭开机启动项

热门文章

  1. 深度神经网络主要模型,深度神经网络预测模型
  2. excel 数组函数入门讲座
  3. 尚硅谷Vue2.0+Vue3.0全套教程视频笔记 + 代码 [P051-100]
  4. paper pass论文查重很好用
  5. houdini安装哪个linux版本,Houdini18.5安装系统环境要求
  6. 机器人动力学-牛顿-欧拉方程
  7. 车载服务机器人app开发源码提供
  8. 如何转换视频格式?推荐这3款视频格式转换工具
  9. 集丰照明|LED 的产业链由哪些部分构成?
  10. 【查找资料】冰点文档下载免费下载百度、豆丁、丁香、畅享、MBALib、道客巴巴、Book118等文库文档