类型 | 字符流 | 字节流 |
File文件 | FileReader、FileWriter |
FileInputStream
、
FileOutputStream
|
内存数组 | CharArrayReader、 CharArrayWriter |
ByteArrayInputStream
、
ByteArrayOutputStream
|
内存字串 | StringReader、StringWriter | |
管道 |
PipedReader
、
PipedWriter
| PipedInputStream、 PipedOutputStream |
FileInputStream 和 FileOutputStream 是文件字节流,是一种节点流文件字节输入流的构造方法:
- FileInputStream("文件名称"),如果文件不存在则FileNotFoundException
- FileInputStream(File)
文件字节输出流的构造方法 :
- FileOutputStream(“文件名称”) 如果文件不存在则新建文件,如果文件存在则覆盖文件内容
- FileOutputStream(String name文件名称, boolean append是否采用追加方式)
FileReader 和 FileWriter 类似
FileInputStream 和 FileOutputStream 两个类属于结点流,第一个类的源端和第二个类的目的端都是磁盘文件,它们的构造方法允许通过文件的路径名来构造相应的流。如:FileInputStream infile = new FileInputStream("myfile.dat");FileOutputStream outfile = new FileOutputStream("results.dat");要注意的是,构造 FileInputStream, 对应的文件必须存在并且是可读的,而构造 FileOutputStream 时,如输出文件已存在,则必须是可覆盖的。
需求: 将存储路径下的data/calcCharNum.txt拷贝到data/cal.txt
- package com.yan2;
-
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.Reader;
- import java.io.Writer;
-
- /*
- * 文件节点流
- * 字节 FileInputStream和FileOutputStream
- *
- * 文件字节输入流的构造方法:
- * - FileInputStream("文件名称"),如果文件不存在则FileNotFoundException
- * - FileInputStream(File)
- * throws或者try/catch
- * 文件字节输出流的构造方法:
- * - FileOutputStream(“文件名称”) 如果文件不存在则新建文件,如果文件存在则覆盖
- * 文件内容
- * - FileOutputStream(String name文件名称, boolean append是否采用追加方式)
- *
- * FileReader和FileWriter类似
- * 字符 FileReader和FileWriter
- */
-
- public class Test1 {
- public static void main(String[] args) {
- File file = new File("data/calcCharNum.txt");
- if (file.exists()) {
- try (Reader r = new FileReader(file); Writer w = new FileWriter("data/cal.txt", true)) {
- char[] arr = new char[8192];
- int len = 0;
- while ((len = r.read(arr)) > 0) {
- w.write(arr, 0, len);
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- System.out.println("出问题了:" + e.getMessage());
- }
- }
- }
- }
-
-
- //构造输出文件流时可以使用两种不同的方式
- //OutputStream os=new FileOutputStream("e:\\dd.txt"); 如果文件不存在则自动创建;如果文件存在则进行覆盖
- //OutputStream os=new FileOutputStream("e:\\dd.txt",true),这里的boolean类型参数 表示是否采用追加的方式写入文件
如果文本则使用 char[] ,如果二进制则使用 byte[]构造器方法
- CharArrayReader(char[] buf)其中char[]就是数据的来源,也就是说Reader就是从char[]中读取数据
- CharArrayRead(char[] buf, int offset, int length)
CharArrayWriter 用于实现向一个字符数组中写入数据,这个数组可以自动调整大小ByteArrayInputStream 、 ByteArrayOutputStream 和 CharArrayReader 以及 CharArrayWriter 类似,支持操作的内容不同而已,操作byte[] 与 char[]
- package com.yan2;
-
- import java.io.CharArrayReader;
- import java.io.CharArrayWriter;
- import java.io.Reader;
- import java.io.Writer;
- import java.util.Scanner;
-
- /*
- * 内存数组节点
- *
- * 如果文本则使用char[],如果二进制则使用byte[]
- *
- * 构造器方法
- * - CharArrayReader(char[] buf)其中char[]就是数据的来源,
- * 也就是说Reader就是从char[]中读取数据
- * - CharArrayRead(char[] buf, int offset, int length)
- *
- * CharArrayWriter用于实现向一个字符数组中写入数据,这个数组可以自动调
- * 整大小
- *
- * ByteArrayInputStream、ByteArrayOutputStream和CharArrayReader以及
- * CharArrayWriter类似,支持操作的内容不同而已,操作byte[]与char[]
- */
- public class Test2 {
- public static void main(String[] args) throws Exception {
- String str = "abc中国人民解放军123";
- char[] arr = str.toCharArray();
- Reader r = new CharArrayReader(arr);
- while (true) {
- int kk = r.read();
- if (kk == -1)
- break;
- System.out.println((char) kk);
- }
- System.out.println("键盘录入数据");
- Scanner sc = new Scanner(System.in);
- Writer w = new CharArrayWriter();
- while (true) {
- String ss = sc.nextLine();
- if ("quit".equals(ss))
- break;
- w.write(ss);
- }
- sc.close();
- // 需要使用CharArrayWriter中定义的特殊方法,获取输出的目标数组
- if (w instanceof CharArrayWriter) {
- CharArrayWriter caw = (CharArrayWriter) w;
- caw.append("dsuhsad");// 向输出的数组末尾添加内容 StringBuilder
- // 获取输出的目标数组
- char[] target = caw.toCharArray();
- System.out.println(new String(target));
- }
- }
- }
- //ByteArrayInputStream、ByteArrayOutputStream和CharArrayReader以及
- //CharArrayWriter类似,支持操作的内容不同而已,操作byte[]与char[]
StringReader用于从一个字串String中读取数据
StringWriter用于给一个StringBuffer中写入数据,实现一个可变长的字串
- package com.yan2;
-
- import java.io.IOException;
- import java.io.Reader;
- import java.io.StringReader;
- import java.io.StringWriter;
- import java.io.Writer;
-
- /*
- *内存字串流
- * StringReader用于从一个字串String中读取数据
- *
- * StringWriter用于给一个StringBuffer中写入数据,实现一个可边长的字串
- */
- public class Test4 {
- public static void main(String[] args) throws IOException {
- String str = "中abc国人民解放军";
- Reader r = new StringReader(str);
- while (true) {
- int kk = r.read();
- if (kk == -1) {
- break;
- }
- System.out.print((char) kk);
- }
-
- Writer w = new StringWriter();
- for (int i = 0; i < 26; i++) {
- w.write(('a' + i));
- }
- // 测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型
- if (w instanceof StringWriter) {
- // 创建StringWriter实例对象
- StringWriter sw = (StringWriter) w;
- // getBuffer()方法,返回流的字符缓冲对象StringBuffer
- StringBuffer ss = sw.getBuffer();
- System.out.println(ss);
- }
- }
- }
- 读写文件使用节点流FileInputStream/FileOutputStream和FileReader/FileWriter,如果操作文本文件,建议使用FileReader/FileWriter,如果操作二进制文件建议使用FileInputStream/FileOutputStream
- 需要建立缓冲区(建立临时文件的方式效率低),可以考虑使用内存节点,例如 CharArrayReader/CharArrayWriter、StringReader/StringWriter和 ByteArrayInputStream/ByteArrayOutputStream
- 如果需要一个二进制缓冲区可以使用ByteArrayInputStream/ByteArrayOutputStream,如果需要一个字符缓存可以使用CharArrayReader/CharArrayWriter、StringReader/StringWriter
- 如果数据量不是特别大使用CharArrayReader/CharArrayWriter更为方便,如果数据量大而且可能需要直接操作缓冲区则使用StringReader/StringWriter
- StringWriter中提供了方法getBuffer():StringBuffer
过滤流就是在节点流的基础上附加功能
处理类型 | 字符流 | 字节流 |
缓存 | BufferedReader、BufferedWriter | BufferedInputStream、BufferedOutputStream |
过滤处理 | FilterReader、FilterWriter | FileInputStream、FileOutputStream |
桥接处理 | InputStreamReader、 OutputStreamWriter | |
对象序列化处理 | ObjectInputStream、ObjectOutputStream | |
数据转换 | DataInputStream、DataOutputStream | |
行数统计 | LineNumberReader | LineNumberInputStream |
回滚处理 | PushbackReader | PushbackInputStream |
打印功能 | PrintWriter | PrintStream |
就是decorate模式中的抽象装饰角色
FilterInputStream/FilterOutputStream和FilterReader/FilterWriter
public class FilterInputStream extends InputStream { // 典型的装饰模式protected volatile InputStream in ; // 被装饰目标protected FilterInputStream ( InputStream in ) { // 通过构造器组装被装饰对象this . in = in ;}public int read () throws IOException { // 调用 Filter 中的 read 方法时实际操作是由被装饰对象实现的return in . read ();}}
所谓的过滤流实际上就是类似上面的加密处理,在输入之后(后置处理,被装饰对象先执行)或者输出之前(前置处理,先处理然后被装饰对象执行)进行一下额外的处理,最终实际操作是调用被装饰对象的方法完成工作,依靠这种装饰模式实现在节点流的基础上附加额外功能。当然也允许多个过滤流嵌套从而达到功能累加的目的
FilterInputStream实际上就是一个装饰抽象角色
自定义流实现循环13加密
- package com.yan3;
-
- import java.io.FileReader;
- import java.io.FilterReader;
- import java.io.IOException;
- import java.io.Reader;
-
- /*
- * 抽象装饰FilterInputStream和FilterOutputStream FilterReader和FilterWriter
- */
- public class Test2 {
- public static void main(String[] args) throws Exception {
- // Reader r = new Round13Reader(new FileReader("data/calcCharNum.txt"));
- Reader r = new Round13Reader(new FileReader("data/round13.txt"));
-
- // Writer w = new FileWriter("data/round13.txt");
- // char[] cc = new char[1024];
- int kk = -1;
- while ((kk = r.read()) != -1) {
- // w.write(kk);
- System.out.print((char) kk);
- }
- r.close();
- // w.close();
- }
- }
-
- class Round13Reader extends FilterReader {
- protected Round13Reader(Reader in) {
- super(in);
- }
-
- @Override
- public int read() throws IOException {
- int kk = super.read();
- // 判断是否是英文字符
- if (kk >= 'A' && kk <= 'Z') {
- return (kk - 'A' + 13) % 26 + 'A';
- } else if (kk >= 'a' && kk <= 'z') {
- return (kk - 'a' + 13) % 26 + 'a';
- }
- return kk;
- }
- }
InputStreamReader 和 OutputStreamWriter 是 java.io 包中用于处理字符流的最基本的类,用来在字节流和字符流之间作为中介:从字节输入流读入字节,并按编码规范转换为字符;往字节输出流写字符时先将字符按编码规范转换为字节。使用这两者进行字符处理时,在构造方法中应指定一定的平台规范,以便把以字节方式表示的流转换为特定平台上的字符表示。转换流可以在构造时指定其编码字符集
- InputStreamReader用于将一个InputStream类型的输入流自动转换为Reader字符流
- OutputStreamWriter用于将一个Writer字符输出流转换为OutputStream字节输出流
- InputStreamReader(InputStream)
- InputStreamReader(InputStream, String)
- InputStreamReader(InputStream, Charset)
- InputStreamReader(InputStream, CharsetDecorder)
- package com.yan3;
-
- import java.io.FileInputStream;
- import java.io.InputStreamReader;
- import java.io.Reader;
- import java.nio.charset.Charset;
-
- /*
- * InputStreamReader构造器
- * - InputStreamReader(InputStream)
- * - InputStreamReader(InputStream, String)
- * - InputStreamReader(InputStream, Charset)
- * - InputStreamReader(InputStream, CharsetDecorder)
- */
- public class Test4 {
- public static void main(String[] args) throws Exception {
- // Reader r = new InputStreamReader(new FileInputStream("data/pavkage-info.java"), "UTF-8");
- Reader r = new InputStreamReader(new FileInputStream("data/package-info.java"), Charset.forName("UTF-8"));// Charset.defaultCharset()默认的字符集
- int kk = -1;
- while (true) {
- kk = r.read();
- if (kk == -1)
- break;
- System.out.print((char) kk);
- }
- }
- }
Reader r = new InputStreamReader ( System . in );int kk = r . read (); // 例如输入的是 “ 中国 ” ,这里实际读取的是 " 中 "// 因为这里读取的是一个字节,所以输入 " 中国 " ,实际读取的是 " 中 " 的一个字节,输出显示为 ?kk = System . in . read ();System . out . println ( " 输入的是: " + ( char ) kk );
InputSteram is=new InputStreamReader(System.in,”iso8859-1”);注意:一般不建议自行设置编码字符集,除非是必须的Reader r = new InputStreamReader ( System . in , "gbk" );int kk = r . read (); // 例如输入的是 " 中国 " ,实际读取的是 " 中 "System . out . println ( " 输入的是: " + ( char ) kk );
- package com.yan3;
-
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.io.OutputStreamWriter;
- import java.io.Reader;
- import java.io.Writer;
- /*
- * ### 桥接转换流
- * InputStreamReader和OutputStreamWriter是java.io包中用于处理字符流的最基本的类,
- * 用来在字节流和字符流之间作为中介:从字节输入流读入字节,并按编码规范转换为字符;往字节输出流写字符时
- * 先将字符按编码规范转换为字节。使用这两者进行字符处理时,在构造方法中应指定一定的平台规范,以便把以字
- * 节方式表示的流转换为特定平台上的字符表示。
- * 转换流可以在构造时指定其编码字符集
- * InputStreamReader用于将一个InputStream类型的输入流自动转换为Reader字符流
- * OutputStreamWriter用于将一个Writer字符输出流转换为OutputStream字节输出流
- */
-
- public class Test3 {
- public static void main(String[] args) throws Exception {
- InputStream is = new FileInputStream("data/package-info.java");
- Reader r = new InputStreamReader(is);
- while (true) {
- // int kk = is.read();
- int kk = r.read();
- if (kk == -1) {
- break;
- }
- System.out.print((char) kk);
- }
-
- OutputStream os = new FileOutputStream("data/out.txt");
- Writer w = new OutputStreamWriter(os);
- w.write("中国人民解放军");
- w.close();
- }
- }