一、缓冲流
1、分类
分类:字节缓冲流 和 字符缓冲流。
字节缓冲流:字节输入缓冲流:BufferedInputStream、字节输出缓冲流:BufferedOutputStream
字符缓冲流:字符输入缓冲流:BufferedReader、字符输出缓冲流:BufferedWriter
2、字节缓冲流
字节缓冲流包括字节输入缓冲流 BufferedInputStream 和 字节输出缓冲流 BufferedOutputStream。
(1)BufferedInputStream
继承关系:
java.lang.Object
|____java.io.InputStream
|____java.io.FilterInputStream
|____java.io.BufferedInputStream
类声明:
public class BufferedInputStream extends FilterInputStream {
private static int DEFAULT_BUFFER_SIZE = 8192;
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
protected volatile byte buf[];
}
由上述代码可以看出:
- BufferedInputStream 中缓冲区使用数组来实现;
- 缓冲区默认大小为 8192 (即8KB);
- 最大缓冲区大小为 Integer 类型所能存储的最大值减 8;
构造方法:
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
BufferedInputStream 有两个构造方法,一个使用默认的缓冲区大小,一个根据传进来的参数 size 设置缓冲区大小。
简单使用:
//字节流
FileInputStream fis = new FileInputStream("C:\\suxing\\test_1.txt");
//字节输入缓冲流
BufferedInputStream bis = new BufferedInputStream(fis);
//程序缓冲区,注意与BufferedInputStream类中的缓冲区区分开
byte[] buf = new byte[1024*4];
int len = -1;
while ((len = bis.read(buf))!=-1){
String str = new String(buf,0,len);
System.out.println(str);
}
//关闭流
bis.close();
(2)BufferedOutputStream
继承关系:
java.lang.Object
|____java.io.OutputStream
|____java.io.FilterOutputStream
|____java.io.BufferedOutputStream
类声明:
public class BufferedOutputStream extends FilterOutputStream {
protected byte buf[];
}
- BufferedOutputStream,内部也同样维护着一个数组作为缓冲区。
构造方法:
public BufferedOutputStream(OutputStream out) {
this(out, 8192);
}
public BufferedOutputStream(OutputStream out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
BufferedOutputStream 有两个构造方法,一个使用默认的缓冲区大小,一个根据传进来的参数 size 设置缓冲区大小。
简单使用:
//字节流
FileOutputStream fos = new FileOutputStream("C:\\suxing\\test_2.txt");
//字节输出缓冲流
BufferedOutputStream bos = new BufferedOutputStream(fos);
String data = "好好学习,天天向上。\r\n";
for (int i = 0;i<10;i++){
bos.write(data.getBytes("utf-8"));
}
//刷新缓冲区
bos.flush();
//关闭流
bos.close();
3、字符缓冲流
字符缓冲流包括字符输入缓冲流 BufferedReader 和 字符输出缓冲流 BufferedWriter。
(1)BufferedReader
继承关系:
java.lang.Object
|____java.io.Reader
|____java.io.BufferedReader
类声明:
public class BufferedReader extends Reader {
private char cb[];
private static int defaultCharBufferSize = 8192;
private static int defaultExpectedLineLength = 80;
}
由上述代码可以看出:
- BufferedReader 使用字符数组作为缓冲区;
- 缓冲区默认大小为 8192;
- 默认行的长度为 80;
构造方法:
public BufferedReader(Reader in, int sz) {
super(in);
if (sz <= 0)
throw new IllegalArgumentException("Buffer size <= 0");
this.in = in;
cb = new char[sz];
nextChar = nChars = 0;
}
public BufferedReader(Reader in) {
this(in, defaultCharBufferSize);
}
BufferedReader 有两个构造方法,一个使用默认的缓冲区大小,一个根据传进来的参数 size 设置缓冲区大小,当传入的数值小于等于0时,会抛出IllegalArgumentException异常。
简单使用:
每次读取一个缓冲区:
FileReader fr = new FileReader("C:\\suxing\\test_2.txt");
//字符缓冲输入流
BufferedReader br = new BufferedReader(fr);
//程序自己的缓冲区
char[] buf = new char[1024];
int len = -1;
String data = null;
while ((len = br.read(buf))!=-1){
data = new String(buf,0,len);
System.out.println(data);
}
//关闭流
br.close();
按行读取文件内容:
FileReader fr = new FileReader("C:\\suxing\\test_2.txt");
//字符缓冲输入流
BufferedReader br = new BufferedReader(fr);
//按行读取全部内容
String line = null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
//关闭流
br.close();
二、内存流
1、分类
内存流有两个:
ByteArrayInputStream:字节数组输入流,用于将字节数组转化成流。
ByteArrayOutoutStream:捕获内存缓冲区中的数据,转化成字节数组。
2、使用
(1)ByteArrayInputStream
继承关系:
java.lang.Object
|____java.io.InputStream
|____java.io.ByteArrayInputStream
类声明:
public class ByteArrayInputStream extends InputStream {
protected byte buf[];
}
ByteArrayInputStream 类中维护着一个字节数组用于接受构造方法转入的待转化为流的字节数组中的数据。
构造方法:
public ByteArrayInputStream(byte buf[]) {
this.buf = buf;
this.pos = 0;
this.count = buf.length;
}
public ByteArrayInputStream(byte buf[], int offset, int length) {
this.buf = buf;
this.pos = offset;
this.count = Math.min(offset + length, buf.length);
this.mark = offset;
}
ByteArrayInputStream 有两个构造方法,一个传入准备转化成流字节数组,另一个传入准备转化成流的字节数组,和数组的起始位置以及数据的长度。
简单使用:
就像两个人面对面打电话:
//待转化成流的数据
byte[] data = "suxingsuxing".getBytes("utf-8");
ByteArrayInputStream bais = new ByteArrayInputStream(data);
int d = -1;
while ((d = bais.read())!=-1){
System.out.print((char)d);
}
System.out.println();
//该流可以不用关,因为数据存在内存中,没有涉及IO
bais.close();
(2)ByteArrayOutputStream
继承关系:
java.lang.Object
|____java.io.OutputStream
|____java.io.ByteArrayOutputStream
类声明:
public class ByteArrayOutputStream extends OutputStream {
protected byte buf[];
}
ByteArrayOutputStream 内部同样维护着一个数组,将捕获的内存缓冲区中的数据转化成字节数组后,存储在该类内部的这个数组中。
构造方法:
public ByteArrayOutputStream() {
this(32);
}
public ByteArrayOutputStream(int size) {
if (size < 0) {
throw new IllegalArgumentException("Negative initial size: "
+ size);
}
buf = new byte[size];
}
ByteArrayOutputStream有两个构造方法,一个无参的构造方法,内部数组默认大小为 32 。另一个有参构造方法,接受一个int值,作为内部数组的大小,该方法会抛出IllegalArgumentException异常。
简单使用:
循环向ByteArrayOutputStream中的数组写入数据。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
//写到该流内部维护的数组中。
for (int i = 0;i<10;i++){
baos.write("hello".getBytes());
}
System.out.println(baos.toString());
baos.close();
(3)使用内存流将大写字符串转换成小写
//待转化成流的数据
String data = "HELLO WORLD";
ByteArrayInputStream bais = new ByteArrayInputStream(data.getBytes());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int d = -1;
while ((d=bais.read())!=-1){
char c = Character.toLowerCase((char)d);
//d = d+32;//处理不了标点符号
baos.write(c);
}
System.out.println(baos.toString());
bais.close();
baos.close();
三、标准输入输出流
1、简介
标准输入输出流有 System.in 和 System.out 。
- System.in 标准输入流,用于控制台的输入数据读到内存中。
- System.out 标准输出流,用于将内存中的数据打印到控制台。
除了标准输入输出流还有打印流 printStream
2、System.out 和 System.in
(1)简单应用
最简单的应用:
//System.in
Scanner input = new Scanner(System.in);
String data = input.next();
//System.out
System.out.println(data);
查看类型:System类中
public final static InputStream in = null;
public final static PrintStream out = null;
System.out 是 PrintStream 类型的。System.in是 InputStream 类型的,但是在实例化的时候,System.in实际上是BufferedInputStream,由于实例化时调用的是本地方法,看不到 ,但是,我们可以通过下面两行代码验证:
System.out.println(System.in.getClass().getName());
System.out.println(System.out.getClass().getName());
输出结果:
java.io.BufferedInputStream
java.io.PrintStream
(2) 将System.in 转化为 字符流读取数据:
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
while(true){
str = br.readLine();
if(str.equals("end")){
break;
}else{
System.out.println(str);
}
}
br.close();
(3)标准输入输出流重定向
利用PrintStream将标准输出流重定向到某个文件:
PrintStream pw = new PrintStream("C:\\suxing\\test_out.txt");
System.setOut(pw);
System.out.println("suxing");
//pw流不能关
将标准输入流重定向到某个文件:
FileInputStream fis = new FileInputStream("C:\\suxing\\test_out.txt");
System.setIn(fis);
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String data = bf.readLine();
System.out.println(data);
(4)PrintStream 的继承关系:
java.lang.Object
|____java.io.OutputStream
|____java.io.FilterOutputStream
|____java.io.PrintStream
(5)类声明:
public class PrintStream extends FilterOutputStream
implements Appendable, Closeable
{}
Appendable接口
Appendable接口的实现类的对象能够被添加 char 序列和值。如果某个类的实例打算接收取自 java.util.Formatter 的格式化输出,那么该类必须实现 Appendable接口。
Closeable接口
Closeable 是可以关闭的数据源或目标。调用 close 方法可释放对象保存的资源(如打开文件)。