Java读取文件的N种方法
1.概述
在这篇文章里, 我们将探索不同的方式从文件中读取数据。
首先, 学习通过标准的的Java类,从classpath、URL或者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);
这两种方法的主要区别是, 当前类的ClassLoader的getResourceAsStream方法,入参路径是从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种方法相关推荐
- 用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 ...
- java遍历文件和归类_java读取文件的两种方法:java.io和java.lang.ClassLoader
java读取文件的两种方法:java.io和java.lang.ClassLoader 什么时候使用java.io,什么时候使用java.lang.ClassLoader呢? (注:要是之前读xml文 ...
- php读取文件内容5种方法
实际应用当中,请注意关闭 fclose($fp); php读取文件内容: -–第一种方法-–fread()--– <?php$file_path= "test.txt";if ...
- 81. read readline readlines 读取文件的三种方法
81. read readline readlines 读取文件的三种方法 文章目录 81. read readline readlines 读取文件的三种方法 1. 读取文件的三种方法 2. rea ...
- java写入文件不覆盖写入_Java写入文件–用Java写入文件的4种方法
java写入文件不覆盖写入 Java provides several ways to write to file. We can use FileWriter, BufferedWriter, ja ...
- java文件写入不覆盖_java写入文件不覆盖写入_Java写入文件–用Java写入文件的4种方法...
java写入文件不覆盖写入 Java provides several ways to write to file. We can use FileWriter, BufferedWriter, ja ...
- Java读取文件内容的六种方法
1.Scanner 第一种方式是Scanner,从JDK1.5开始提供的API,特点是可以按行读取.按分割符去读取文件数据,既可以读取String类型,也可以读取Int类型.Long类型等基础数据类型 ...
- python中几种读取文件的方法_python 逐行读取文件的几种方法
Python四种逐行读取文件内容的方法 下面四种Python逐行读取文件内容的方法, 分析了各种方法的优缺点及应用场景,以下代码在python3中测试通过, python2中运行部分代码已注释,稍加修 ...
- python读取文件多行内容-python 逐行读取文件的几种方法
Python四种逐行读取文件内容的方法 下面四种Python逐行读取文件内容的方法, 分析了各种方法的优缺点及应用场景,以下代码在python3中测试通过, python2中运行部分代码已注释,稍加修 ...
- Shell按行读取文件的3种方法
Shell按行读取文件的方法有很多,常见的三种方法如下: 要读取的文件: 1 [root@mini05 20180930-2]# cat file.info 2 111 3 222 4 333 444 ...
最新文章
- Building and running Node.js for Android
- 进程在与Windows Process Activation Service通信时出现严重错误 w3wp.exe错误
- Win 驱动编程 - 内核里操作注册表
- 30段极简Python代码:这些小技巧你都Get了么?
- 润乾报表列太多导致渲染速度慢_报表自动化: 如何选择可视化大屏开发利器
- highCharts文档与演示效果的使用 - 文档(应用型)解读
- SQL语句优化常见方法
- 犀牛软件rhinoceros的参数化设计插件草蜢grasshopper的安装
- 【雕爷学编程】Arduino动手做(84)---DS1307时钟模块
- Redis3.x 源码安装
- 程序员课外拓展004:Photoshop CC 2018详细图文安装教程
- html中文字放在图片下边,css图片下边怎么加字
- dede所有目录模板全解
- 解决xshell中数字小键盘不能使用的问题
- 什么是大数据与智能数据?什么是惯性测量单元与GNSS?
- 熟悉Hive 实验2
- java中什么是结果集,Java中对数据库查询结果集进行操作的对象是()
- 你们要的Java学习路线图,来喽
- MATLAB中对矩阵的变换
- WIN10 怎么关闭开机启动项
热门文章
- 深度神经网络主要模型,深度神经网络预测模型
- excel 数组函数入门讲座
- 尚硅谷Vue2.0+Vue3.0全套教程视频笔记 + 代码 [P051-100]
- paper pass论文查重很好用
- houdini安装哪个linux版本,Houdini18.5安装系统环境要求
- 机器人动力学-牛顿-欧拉方程
- 车载服务机器人app开发源码提供
- 如何转换视频格式?推荐这3款视频格式转换工具
- 集丰照明|LED 的产业链由哪些部分构成?
- 【查找资料】冰点文档下载免费下载百度、豆丁、丁香、畅享、MBALib、道客巴巴、Book118等文库文档