缓冲流是套接在响应的节点流之上,对续写的数据提供缓冲的功能,提高读写的效率,同时增加了一些新方法以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。为了解决以上弊端,采用缓存流。缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。
- package com.yan3;
-
- import java.io.BufferedReader;
- import java.io.FileReader;
- import java.io.Reader;
-
- /*
- * ### 缓冲流
- * 缓冲流是套接在响应的节点流之上,对续写的数据提供缓冲的功能,提高读写的
- * 效率,同时增加了一些新方法
- *
- * 以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬
- * 盘。 如果读写的频率比较高的时候,其性能表现不佳。为了解决以上弊端,采用
- * 缓存流。
- *
- * 缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都
- * 是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。
- */
- public class Test5 {
- public static void main(String[] args) {
- long start = System.currentTimeMillis();
- // useReader(); //207ms
- useReader2(); // 152ms
- long end = System.currentTimeMillis();
- System.out.println(end - start + "ms");
- }
-
- public static void useReader() {
- try (Reader r = new FileReader("data/calcCharNum.txt")) {
- while (true) {
- int kk = r.read();
- if (kk == -1) {
- break;
- }
- System.out.print((char) kk);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- public static void useReader2() {
- try (Reader r = new BufferedReader(new FileReader("data/calcCharNum.txt"))) {
- while (true) {
- int kk = r.read();
- if (kk == -1) {
- break;
- }
- System.out.print((char) kk);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- BufferedReader(Reader)不定义缓存大小,默认8192
- BufferedReader(Reader in, int size)size为自定义缓冲区的大小
- BufferedWriter(Writer)
- BufferedWriter(Writer out, int size)size为自定义缓冲区的大小
- BufferedInputStream(InputStream)
- BufferedInputStream(InputStream in, int size)size为自定义缓冲区的大小
- BufferedOutputStream(OutputStream)
- BufferedOutputStream(OuputStream out, int size)size为自定义缓冲区的大小
BuffedReader 提供了一个方法 readLine():String ,但是 BufferedInputStream 中并没有这个
- BufferedReader提供了readLine方法用于读取一行字符串,以\r或\n分割(换行符)
如果读取内容为null,则表示读取到了流的末尾readLine方法会自动剔除本行内容末尾的换行符
- BufferedWriter提供了newLine方法用于写入一个行分隔符
对于输出的缓冲流,写入的数据会先在内存中缓存,使用 flush 方法会使内存中的数据立即写出
System.in:InputStream 用于指代系统默认的输入设备 — 键盘方法 read():int 可以实现代码执行到这里则会阻塞等待,只要输入数据为止
- package com.yan3;
-
- import java.io.BufferedReader;
- import java.io.InputStreamReader;
-
- /*
- * 缓冲输入流的方法
- *
- * BuffedReader提供了一个方法readLine():String,但是BufferedInputStream中并
- * 没有这个
- *
- * - BufferedReader提供了readLine方法用于读取一行字符串,以\r或\n分割(换行符)
- - 如果读取内容为null,则表示读取到了流的末尾
- - readLine方法会自动剔除本行内容末尾的换行符
-
- - BufferedWriter提供了newLine方法用于写入一个行分隔符
- 对于输出的缓冲流,写入的数据会先在内存中缓存,使用flush方法会使内存中的
- 数据立即写出
- */
- public class Test7 {
- public static void main(String[] args) throws Exception {
- // 要求用户输入一个合法的整型数
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- int age = 0;
- while (true) {
- String ss = br.readLine();// BufferedReader提供的特殊方法,用于实现整行读取
- try {
- age = Integer.parseInt(ss.trim());
- if (age >= 18 && age <= 65) {
- break;
- } else {
- System.out.println("年龄范围不合法!!!");
- }
- } catch (Exception e) {
- System.out.println("格式错误!");
- }
- }
- System.out.println("合法的年龄输入为 " + age);
- }
- }
使用缓存流并没有添加什么额外方法,只是它能够在执行过程中自动引入缓存,从而提高执行效率过滤流使用必须有对应的节点流,因为过滤流是装饰节点流,不是有具体的操作目标new BufferedReader(new FileReader(..)) 或 new BufferedWriter(new FileWriter()) 实际上使用的还是Reader/Writer那些方法,这里从编码的角度上说,没有任何区别,但是从执行性能上说,比FileReader/Writer效率高,可以减少磁盘的读写次数执行 close 方法会自动关闭被装饰的对象,所以不需要再关闭 FileReader 和 FileWriter执行 flush 会自动刷新数据到节点流上,但是并没有执行关闭流。针对输出流关闭时会自动先 flush 缓存再执行关闭
使用java的输入/输出流技术将一个文本文件的内容按行读出,每读出一行就顺序添加行号,并写入到另一个文件中。
- package com.yan4;
-
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileReader;
- import java.io.FileWriter;
- /*
- * 使用java的输入/输出流技术将一个文本文件的内容按行读出,每
- * 读出一行就顺序添加行号,并写入到另一个文件中。
- */
-
- public class Exec01 {
- public static void main(String[] args) throws Exception {
- try (BufferedReader br = new BufferedReader(new FileReader("src/com/yan1/Test1.java"));
- BufferedWriter bw = new BufferedWriter(new FileWriter("data/out1.txt"))) {
- int cc = 0;
- while (true) {
- String ss = br.readLine();
- if (ss == null)
- break;
- bw.write(++cc + "\t");
- bw.write(ss);
- bw.newLine();
- }
- }
- }
- }
DataInputStream 和 DataOutputStream 两个类创建的对象分别被称为数据输入流和数据输出流。这是很有用的两个流,它们允许程序按与机器无关的风格读写Java 数据。所以比较适合于网络上的数据传输。这两个流也是过滤器流,常以其它流如InputStream 或 OutputStream 作为它们的输入或输出DataInputStram和 DataOutputStream 分别继承自 InputStream 和 OuputStream ,属于过滤流,需要分别套接在InputStream 和 OutputStream 类型的节点流上
- 只有字节流,没有对应的字符流
DataInputStream和DataOutputStream 提供了可以存取与机器无关的 Java 原始类型数据的方法DataInputSteram 和 DataOutputStream 构造方法为
- DataInputStream(InputStream)
- DataOutputStream(OutputStream)
用数据输出流将斐波那契级数的前二十项存放在fei.dat文件中。
- package com.yan3;
-
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.EOFException;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
-
- /*
- * 用数据输出流将斐波那契级数的前二十项存放在fei.dat文件中
- */
- public class Test81 {
- public static void main(String[] args) throws Exception {
- DataOutputStream dos = new DataOutputStream(new FileOutputStream("data/fei.dat"));
- for (int i = 0; i < 20; i++) {
- int num = fei(i);
- dos.writeInt(num);
- }
- dos.close();
-
- DataInputStream dis = new DataInputStream(new FileInputStream("data/fei.dat"));
- try {
- while (true) {
- int kk = dis.readInt();
- System.out.print(kk + "\t");
- }
- } catch (EOFException e) {
- System.out.println("文件读取完毕");
- }
- dis.close();
- }
-
- public static int fei(int pos) {
- if (pos == 0) {
- return 0;
- }
- if (pos == 1) {
- return 1;
- }
- return fei(pos - 1) + fei(pos - 2);
- }
- }
从fei.dat文件中读出数列,显示输出,并计算累加和
- package com.yan3;
-
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.EOFException;
-
- /*
- * 1、用数据输出流将菲波那契级数列的前二十项存放内存中。
- * 2、从内存中读出数列,显示输出,并计算累加和。
- */
- public class Test82 {
- public static void main(String[] args) throws Exception {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- DataOutputStream dos = new DataOutputStream(baos);
- for (int i = 0; i < 20; i++) {
- int num = fei(i);
- dos.writeInt(num);
- }
- byte[] data = baos.toByteArray();
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));
- int sum = 0;
- while (true) {
- try {
- int kk = dis.readInt();
- sum += kk;
- System.out.println(kk);
- } catch (EOFException e) {
- System.out.println("读取完毕!");
- break;
- }
- }
- System.out.println("累加和为 " + sum);
- }
-
- public static int fei(int n) {
- if (n < 0)
- throw new IllegalArgumentException();
- if (n == 0)
- return 0;
- if (n == 1)
- return 1;
- return fei(n - 1) + fei(n - 2);
- }
- }
产生5000个1~9999之间的随机整数,将其存入二进制数据文件a.data中
- package com.yan4;
-
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.util.Random;
-
- /*
- * 作业题:
- * 练习:编写一个程序实现以下功能:
- * (1)产生5000个1~9999之间的随机整数,将其存入二进制数据文件a.data中。
- * (2)从文件中读取所有整数(文件中都是整数,但是个数未知),并计算其最大值、最小值和平均值并输出结果。
- */
- public class Exec02 {
- public static void main(String[] args) throws Exception {
-
- DataOutputStream dos = new DataOutputStream(new FileOutputStream("data/a.data"));
- Random r = new Random();
- for (int i = 0; i < 5000; i++) {
- dos.writeInt(r.nextInt(9999));
- }
- DataInputStream dis = new DataInputStream(new FileInputStream("data/a.data"));
- for (int i = 0; i < 5000; i++) {
- int kk = dis.readInt();
- System.out.print(kk + "\t");
- }
- dis.close();
- }
- }
PrintStream 和 PrintWriter 都属于输出流,分别针对字节和字符PrintWriter 和 PrintStream 都提供了重载的 print 和 println 方法用于输出多种类型数据print(Object):void
- 输出引用类型,实际上是调用对象的toString方法转换为String进行输出
println 表示输出后自动换行
- PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
- PrintWriter和PrintStream有自动的flush功能 textOut.flushBuffer();
PrintWriter(Writer)PrintWriter(Writer out, boolean autoFlush) 自动刷新 ----println
- package com.yan3;
-
- import java.io.FileWriter;
- import java.io.PrintWriter;
-
- /*
- * 打印流 println和print
- *
- * PrintStream和PrintWriter都属于输出流,分别针对字节和字符
- *
- * PrintWriter和PrintStream都提供了重载的print和println方法
- * 用于输出多种类型数据
- *
- * print(Object):void
- - 输出引用类型,实际上是调用对象的toString方法转换为String进行输出
- ```java
- public void println(Object x) {
- String s = String.valueOf(x); //调用String类中的静态方法将object类型的数据转换为字符串
- synchronized (this) {
- print(s);
- newLine(); //print('\n')
- }
- }
- //String中的valueOf方法的定义
- public static String valueOf(Object obj) {
- return (obj == null) ? "null" : obj.toString(); //如果输出对象非空,则调用对象的toString方法
- }
- ```
- println表示输出后自动换行
- - PrintWriter和PrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
- - PrintWriter和PrintStream有自动的flush功能`textOut.flushBuffer();`
- PrintWriter(Writer)
- PrintWriter(Writer out, boolean autoFlush)自动刷新----println
- */
- public class Test9 {
- public static void main(String[] args) throws Exception {
- // 注意实际上允许直接new PrintWriter(System.out)
- PrintWriter pw = new PrintWriter(new FileWriter("data/out4.dat"));
- for (int i = 0; i < 10; i++) {
- pw.println(i);
- // pw.print(i);
- }
- pw.close();
- }
- }