1.概述
在这篇文章里, 我们将探索不同的方式从文件中读取数据。
首先, 学习通过标准的的Java类,从classpath、URL或者Jar中加载文件。
然后,学习通用BufferedReader,Scanner,StreamTokenizer,DataInputStream,SequenceInputStream,FileChannel读取文件内容。也会讨论如何读取UTF-8编码的文件。
最后,学习Java7和Java8中新的加载和读取文件的技术。
在启动Eclipse后左边方框中单机右键,在右键菜单中选择导入(英文版Eclipse选import)选项,然后选择已存在的项目(英文版Existing Project into Workplace),在所有java文件前选对号后之后点完成(英文版finish),就完成了java程。
2.准备
2.1 输入文件
这篇文章的很多示例,从名为fileTest.txt的文件读取文本内容,文件包含
Hello,World!
java源代码是txt格式的.java文件,用记事本就可以打开。用eclipse打开java文件的方式是:如果java文件是一个eclipse工程(根目录带有.project文件),用file/import/general/exist java project/(大概是)然后找到你的目录。否则。
有少量示例, 我们会读取不同的文件, 示例中会有说明。
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(&34;);}}return resultStringBuilder.toString();}
3.从Classpath读取文件
3.1 使用标准Java
从src/main/resources读取文件fileTest.txt
@Testpublic void test() throws IOException {String expectedData = &34;;Class<ReadFileTest> clazz = ReadFileTest.class;InputStream inputStream = clazz.getResourceAsStream(&34;);String data = readFromInputStream(inputStream);Assert.assertThat(data,containsString(expectedData));}
在上面的代码中,我们通过当前类的getResourceAsStream方法加载文件,入参是绝对路径。
(1)新建一个项目可以是java project也可以就用project (2)有了工程后直接在默认包下运行java文件复制java文件在src上右击选择Paste(会自动粘刚刚复制的java文件)这样就可以在默认包下编辑运行java文件 (3)打开project 。
ClassLoader中相同的方法也可以使用。
ClassLoader classLoader = getClass().getClassLoader();InputStream inputStream = classLoader.getResourceAsStream(&34;);String data = readFromInputStream(inputStream);
这两种方法的主要区别是, 当前类的ClassLoader的getResourceAsStream方法,入参路径是从classpath开始。
而类实例的入参是相对于包路径,但路径开始使用&39;符号, 也是绝对路径。
特别要注意的是, 文件打开读取完数据后, 始终需要关闭
inputStream.close();
java不能直接打开,你可以进入命令行模式或者使用ide运行java代码。使用命令行模式运行java程序。win + R,输入cmd,然后输入java和javac,确保java已经成功安装。找到编写好的文件位置,用cd 命令进入 比如,我的文件在桌面,。
3.2 使用commons-io库
另一个比较常用的方法是使用commons-io包里的FileUtils.readFileToString方法。
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>1.4</version></dependency>
怎么在电脑上找到java文件,@Testpublic void useCommonIO() throws IOException {String expectedData = &34;;ClassLoader classLoader = getClass().getClassLoader();File file = new File(classLoader.getResource(&34;).getFile());String data = FileUtils.readFileToString(file,&34;);assertEquals(expectedData,data.trim());}
@Testpublic void useCommonIO2() throws IOException {String expectedData = &34;;FileInputStream fis = new FileInputStream(&34;);String data = IOUtils.toString(fis,&34;);assertEquals(expectedData,data.trim());}
4.BufferedReader
@Testpublic void bufferedReader() throws IOException {String expected_value = &34;;String file =&34;;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 = &34;;Path path = Paths.get(&34;);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 = &34;;Path path = Paths.get(&34;);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)。
Scanner默认的定界符是空格。它适用于从控制台读取输入或者内容有固定定界符的内容时。
7.StreamTokenizer
tokenizer会指出下一个token的类型,String或Number。
tokenizer.nval - 如果类型为Number时,读取该字段
tokenizer.sval - 如果类型为String时,读取该字段
8.DataInputStream
运行java文件的方法:1、打开dos界面,进入java文件所在路径。2、编译java文件,如:javac Test.java;3、运行java文件,如:java Test;如图:
如果要读取二进制文件或者原生数据,可以使用DataInputStream
@Testpublic void whenReadWithDataInputStream() throws IOException {String expectedValue = &34;;String file =&34;;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。
@Testpublic void whenReadWithFileChannel()throws IOException {String expected_value = &34;;String file = &34;;RandomAccessFile reader = new RandomAccessFile(file,&34;);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编码的文件
@Testpublic void whenReadUTFEncodedFile()throws IOException {String expected_value = &34;;String file = &34;;BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file),&34;));String currentLine = reader.readLine();reader.close();assertEquals(expected_value,currentLine);}
1、打开.java文件所在的目录:2、右键选择打开方式,然后选择“记事本”即可:3、打开后的效果:
11.从URL读取数据
@Testpublic void readFromURL() throws IOException {URL urlObject = new URL(";);URLConnection urlConnection = urlObject.openConnection();InputStream inputStream = urlConnection.getInputStream();String data = readFromInputStream(inputStream);}
12.从jar包中读取文件
我们的目标是读取junit-4.12.jar包中的LICENSE-junit.txt文件。clazz只需要这个Jar中的类就行。