Java程序中,对于数据的输入/输出
操做以“流(stream)”
的方式进行。数组
字节流(8bit)
,字符流(16 bit)
输入流
,输出流
节点流
,处理流
关于字节流和字符流的区别:单元测试
输入流和输出流测试
节点流和处理流 spa
节点流
:直接从数据源或者目的地读写数据3d
处理流
:不直接链接到数据源或目的地,而是“链接”在已存在的流(节点流或处理流)之上,经过对数据的处理为程序提供更为强大的读写功能。code
Java IO流体系 对象
Java中IO流体系以下表所示,最基本的四个抽象基类分别是:InputStream
、OutputStream
、Reader
、Writer
。表格每一列的类都是继承与第一行的抽象基类的。blog
一般一个流的使用由如下4个步骤组成:继承
好比以FileReader流为例,那么它的使用步骤是:图片
虽然Java IO流体系有众多的类,可是全部的流都基本按照这几个步骤来使用的。下面记录一下FileReader的使用,数据的读入操做。
@Test public void testFileReader() throws IOException { // 抛出异常 // 1. 实例化File类对象,指明要操做的文件 File file = new File("Hello.txt"); // 2. 提供具体的流 FileReader fr = new FileReader(file); // 3. 数据的读入 // read():返回读入的一个字符,若是达到文件末尾,那么返回-1 int data = fr.read(); while(data != -1){ System.out.print((char)data); data = fr.read(); } // 4. 流的关闭操做 fr.close(); }
上面例子中,经过File类实例化了一个File对象,而后将其当作参数传入了FileReader类进行实例化,以后调用read()方法进行数据的读入,最后执行流的关闭。
关于上面代码有几个须要注意的点:
File file = new File("Hello.txt");
这段代码使用的是相对路径,若是是使用IDEA进行编写的,那么这个相对路径在单元测试方法和main方法中有所区别。在单元测试方法中使用相对路径,那么相对的是模块的路径,而在main方法中相对的是项目的路径。好比,这里模块名Day07,这个模块下有文件Hello.txt,而模块位于项目JavaSenior下,那么File类实例化后的实例文件路径以下代码所示:public class FileReaderTest { // 在main方法中,输出:D:\code\Java\JavaSenior\Hello.txt public static void main(String[] args) { File file = new File("Hello.txt"); System.out.println(file.getAbsolutePath()); } // 在单元测试方法中,输出:D:\code\Java\JavaSenior\Day07\Hello.txt @Test public void test4(){ File file = new File("Hello.txt"); System.out.println(file.getAbsolutePath()); } }
@Test public void test2(){ FileReader fr = null; try{ File file = new File("Hello.txt"); fr = new FileReader(file); int data; while ((data = fr.read()) != -1){ System.out.println((char)data); } }catch (IOException e){ e.printStackTrace(); }finally { try { if (fr != null){ fr.close(); } } catch (IOException e) { e.printStackTrace(); } } }
read()
方法:读取单个字符。做为整数读取的字符,范围在0-65535之间(2个字节的Unicode码),若是已到达流的末尾,则返回-1。read(char cbuf[])
:将字符存入数组,而且返回本次读取的字符数,若是到达流的末尾,则返回-1。@Test public void test3() { FileReader fr = null; try { // 1. File类的实例化 File file = new File("Hello.txt"); // 2. FileReader流的实例化 fr = new FileReader(file); // 3. 读入的操做 char[] cbuf = new char[5]; int len; /* 假如Hello.txt里的文件内容是helloworld123,这里的read(cbuf)指的是读取5个字符, 即第一次读取hello,返回5,第二次读取world,返回5, 第三次读取123,由于只有123了,返回3,第四次返回-1。 因此3次循环,len变量的值为5,5,3,最后一次为-1。 */ while ((len = fr.read(cbuf)) != -1) { // 遍历操做错误的写法 // for (int i = 0; i < arr.length; i++) { // System.out.println(arr[i]); // } // 正确的遍历操做一: // for (int i = 0; i < len; i++) { // System.out.print(arr[i]); // } // 错误的写法二: // String str = new String(arr); // System.out.println(str); // 正确的写法二: String str = new String(cbuf,0,len); System.out.print(str); } }catch (IOException e){ e.printStackTrace(); }finally { // 4. 流资源的关闭 try { if (fr != null) { fr.close(); } }catch (IOException e){ e.printStackTrace(); } } }
未完待续...