什么是节点流、转换流、处理流?
- 节点流:FileInputStream FileOutputStream FileReader FileWriter
- 处理流:BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter InputStreamReader OutputStreamWriter
- 节点流是直接处理数据源的类
- 处理流是处理其他流的类
一、字节流
OutputStream/Inputstream
OutputStream为抽象类,表示输出字节流的所有类的超类
Inputstream为抽象类,表示输出字节流的所有类的超类
1. FileOutputstream(文件输出流)
(1)构造函数
FileOutputStream(File file)
FileOutputStream(String filePath)
eg1.
//如果aaa文件夹存在b.txt文件不存在的话,可以创建该文件,但是aaa文件夹不存在会报错
File file = new File("D:/aaa/b.txt"); FileOutputStream fos = new FileOutputStream(file);
//第二个参数表示是否在原来的基础上进行追加数据,运行2次程序,同样的数据存入两次,上面的构造方法不管多少次都只显示一遍数据
fos = new FileOutputStream("D:/aaa/b.txt", true);
(2)写入方法
write(byte[] b),将 b.length 个字节从指定 byte 数组写入此文件输出流中。
write(byte[] b, int off, int len),将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
eg1.
fos.write(97);
fos.write('\r');
fos.write('\n');
eg2.
String str = "hello 中文\r\n";
byte[] bytes = str.getBytes();
fos.write(bytes);
2.FileInputStream(文件输入流)
(1)构造函数
FileInputStream(File file)
FileInputStream(String filePath)
- //如果b.txt文件不存在,会报错
File file = new File(“D:/aaaa/b.txt”);
(2)读取方法
read(),从此输入流中读取一个数据字节。
read(byte[] b),从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。
eg.
byte[] bytes = new byte[102];
int readInt = fis.read(bytes);
while(readInt != -1){
fos.write(bytes, 0, readInt);
readInt = fis.read(bytes);
}
!!注意要如何把读入文件中的中文输出到控制台
eg1.中文字符输出为乱码
int i = fis.read();
while(i != -1){
//中文字符输出为乱码
System.out.print((char)i);
i = fis.read();
}
eg2.中文字符正常输出
byte[] bytes=new byte[102];
int i = fis.read(bytes);
while(i != -1){
System.out.println(new String(bytes, 0, i));
i = fis.read(bytes);
}
3.BufferedOutputStream
- 该类实现缓冲的输出流。通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。
(1)构造方法
BufferedOutputStream(OutputStream out),将数据写入指定的底层输出流。
BufferedOutputStream(OutputStream out, int size),将具有指定缓冲区大小的数据写入指定的底层输出流。
eg.
FileOutputStream fos = new FileOutputStream("d:/day15/abc.txt");
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] bytes = "abc撒飞洒发的32sdf@#$23".getBytes();
bos.write(bytes);
bos.flush();
4.BufferedInputStream
- BufferedInputStream 为另一个输入流添加一些功能,即缓冲输入以及支持 mark 和 reset 方法的能力。
- 在创建 BufferedInputStream 时,会创建一个内部缓冲区数组。
- 在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。
(1)构造方法
BufferedInputStream(InputStream in),创建一个内部缓冲区数组并将其存储在 buf 中
BufferedInputStream(InputStream in, int size),创建一个长度为 size 的内部缓冲区数组并将其存储在 buf 中。
eg.
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("d:/day15/abc.txt")));
byte[] bytes = new byte[1024];
int length = bis.read(bytes);
StringBuffer sb = new StringBuffer();
while(length != -1){
//sb.append(new String(bytes));
System.out.println(new String(bytes));
length = bis.read(bytes);
}
//System.out.println(sb);
5.ObjectOutputStream
ObjectInputStream
二、字符流
Reader/Writer
Reader读取字符流的抽象类
Writer写入字符流的抽象类
1.FileReader/FileWriter
(1)FileReader(File file)
FileReader(String filePath)
(2)FileWriter(File file)
FileWriter(String filePath)
FileWriter(String fileName, boolean append),可以在原来的基础上进行追加数据
eg.
FileWriter fw = new FileWriter("d:/abc.txt");
fw.write("sdfsdf沙发沙发沙发sdfasf@#$%$\r\n");
fw.write("sdfsdf沙发沙发沙发sdfasf@#$%$\r\n");
fw.write("sdfsdf沙发沙发沙发sdfasf@#$%$\r\n");
fw.flush();
fw.close();
FileReader fr = new FileReader("d:/abc.txt");
char[] chars = new char[512];
int length = fr.read(chars);
while(length != -1){
System.out.println(chars);
length = fr.read(chars);
}
2.BufferedWriter
- 该类提供了 newLine() 方法,它使用平台自己的行分隔符概念,此概念由系统属性 line.separator 定义。
- 并非所有平台都使用新行符 (‘\n’) 来终止各行。因此调用此方法来终止每个输出行要优于直接写入新行符。
(1)构造函数
BufferedWriter(Writer out),创建一个使用默认大小输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz),创建一个使用给定大小输出缓冲区的新缓冲字符输出流。
eg.
FileWriter fw = new FileWriter("d:/day15/abc.txt");
BufferedWriter bw = new BufferedWriter(fw);
bw.write("宿舍的发顺丰");
bw.newLine();
bw.write(98);
bw.write("宿舍的发顺丰");
bw.write(98);
bw.write("宿舍的发顺丰");
bw.flush();
bw.close();
3.BufferdReader
- 从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
- 可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。
- 通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。
因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。
例如,
BufferedReader in = new BufferedReader(new FileReader("foo.in"));
将缓冲指定文件的输入。如果没有缓冲,则每次调用 read() 或 readLine() 都会导致从文件中读取字节,并将其转换为字符后返回,而这是极其低效的。
(1)构造函数
BufferedReader(Reader in),创建一个使用默认大小输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz),创建一个使用指定大小输入缓冲区的缓冲字符输入流。
(2)读取方法
readLine(),读取一个文本行
eg.
FileReader fr = new FileReader("d:/day15/abc.txt");
BufferedReader br = new BufferedReader(fr);
String str = br.readLine();
StringBuffer sb = new StringBuffer();
while(str != null){
sb.append(str + "\r\n");
str = br.readLine();
}
System.out.println(sb);
br.close();
三、转换流
1.OutputStreamReader
- OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节
- 每次调用 write() 方法都会导致在给定字符(或字符集)上调用编码转换器。
- 在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对多数用途来说已足够大。
- 注意,传递给 write() 方法的字符没有缓冲。
为了获得最高效率,可考虑将 OutputStreamWriter 包装到 BufferedWriter 中,以避免频繁调用转换器。
例如:
Writer out = new BufferedWriter(new OutputStreamWriter(System.out));
2.InputStreamReader
- InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。
- 每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。
- 要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。
例如:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
(1)构造函数
InputStreamReader(InputStream in),创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName),创建使用给定字符集的 InputStreamReader。
例:
FileOutputStream fos = new FileOutputStream(new File("d:/day15/abc.txt"));
BufferedOutputStream bos = new BufferedOutputStream(fos);
OutputStreamWriter osw = new OutputStreamWriter(bos);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("adsfs");
bw.newLine();
InputStream is = System.in;
BufferedInputStream bis = new BufferedInputStream(is);
InputStreamReader isr = new InputStreamReader(bis);
BufferedReader br = new BufferedReader(isr);
System.out.println(br.readLine());
四、处理流
五、节点流