java基础---缓冲流、数据流、打印流

缓冲流

缓冲流是套接在响应的节点流之上,对续写的数据提供缓冲的功能,提高读写的效率,同时增加了一些新方法
以介质是硬盘为例,字节流和字符流的弊端:在每一次读写的时候,都会访问硬盘。 如果读写的频率比较高的时候,其性能表现不佳。为了解决以上弊端,采用缓存流。
缓存流在读取的时候,会一次性读较多的数据到缓存中,以后每一次的读取,都是在缓存中访问,直到缓存中的数据读取完毕,再到硬盘中读取。
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 表示输出后自动换行
  • PrintWriterPrintStream的输出操作不会抛出异常,用户通过检测错误状态获取错误信息
  • PrintWriterPrintStream有自动的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();
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值