缓冲流、转换流、序列化流、打印流

一 缓冲流

1.1 概述

缓冲流,也叫高效流,是对4个基本的FileXxx 流的增强,所以也是4个流,按照数据类型分类:

  • 字节缓冲流: BufferedInputStream , BufferedOutputStream

  • 字符缓冲流: BufferedReader , BufferedWriter

1.2 字节缓冲流

构造方法

public BufferedInputStream(InputStream in) :创建一个 新的缓冲输入流。

public BufferedOutputStream(OutputStream out): 创建一个新的缓冲输出流。 参数OutputStream out:字节输出流

我们可以传递FileOutputStream缓冲流会给FileOutputStream增加缓冲区,提高FileOutputStream的写入效率,int size:指定缓冲流内部缓冲区的大小

使用步骤

1,创建FileOutputStream对象,构造方法指定绑定要输出的目的地

2,创建BufferedOutputStream对象,构造方法传递FileOutputStream对象,提高FileOutputStream效率。

3,使用BufferedOutputStream对象中的write,把数据写入到内部缓冲区

4,使用BufferedOutputStream对象中的flush,把缓冲区的数据刷新到文件中。

5,释放资源,会先调用flush方法刷新数据,第4部可以省略

1.3 字符缓冲流

构造方法

public BufferedReader(Reader in) :创建一个 新的缓冲输入流。

public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。

使用步骤:

1,创建FileInputStream对象,构造方法指定绑定要输出的目的地

2,创建BufferedInputStream对象,构造方法传递BufferedInputStream对象,提高BufferedInputStream效率。

3,使用BufferedInputStream对象中的read,读取文件

4,释放资源,会先调用flush方法刷新数据,第4部可以省略

特有方法

BufferedReader: public String readLine() : 读一行文字。

行的终止符号:通过下列字符之一即可认为某行终止:换行('\n')、回车('\r')

返回值:包含改行内容的字符串,不包括任何终止符,如果已经到达流末尾,则返回null

BufferedWriter: public void newLine() : 写一行行分隔符,由系统属性定义符号。

使用步骤:

1,创建字符缓冲输入流对象,构造方法中传递字符输入流

2,使用字符缓冲输入流对象中的额方法read/readline读取文本

3,释放资源

1.4 练习:文本排序

对文本的内容进行排序

`public class Test1215 {
public static void main(String[] args) throws IOException {
    //1,创建一个HashMap集合对象,可以存储每行文本的序号;value:存储每行的文本
    HashMap<String,String> map = new HashMap<>();
    //2,创建字符缓冲流对象,构造方法中绑定字符输入流,文件路径
    BufferedReader br = new BufferedReader(new FileReader("c:\\in.txt"));
    //3,创建字符缓冲输入流,构造方法中绑定字符输出流
    BufferedWriter bw = new BufferedWriter(new FileWriter("c:\\out.txt"));
    //4,使用字符缓冲输入流中的方法readline,逐行读取文本,创建一个字符line
    String line;
    //增强for循环,line不为空
    while( (line = br.readLine())!=null){
        //5,对读取到的文本进行切割,获取行中的序号和文本内容
        String[] arr =  line.split("\\.");
        //6.把切割好的序号和文本的内容存储到HashMap中,(key)序号是有序的,自动排序1.2.3...
        map.put(arr[0],arr[1]);
    }
    //7,遍历HashMap集合,获取每一个键值对
   for(String key:map.keySet()){
       String value = map.get(key);
      // 8,把每一个键值对,拼接为一个文本行
       line = key +"."+ value;
       //9,把拼接好的文本,使用字符缓冲输出流中的额方法write写入到文本中
       bw.write(line);
       bw.newLine();

   }
   //10,释放资源
   bw.close();
   br.close();
}
}`

二 转换流

2.1 字符编码

计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。

将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。

字符编码Character Encoding : 就是一套自然语言的字符与二进制数之间的对应规则。

字符集

字符集 Charset :也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。

计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符 集有ASCII字符集、GBK字符集、Unicode字符集等。

win7 或者 win10 简体中文用的都是GBK字符集

Unicode字符集 :

Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。

最为常用的UTF-8编码。 UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则: 1. 128个US-ASCII字符,只需一个字节编码。 2. 拉丁文等字符,需要二个字节编码。 3. 大部分常用字(含中文),使用三个字节编码。 4. 其他极少使用的Unicode辅助字符,使用四字节编码。

2.2 编码引出的问题

使用FileReader 读取项目中的文本文件。由于IDEA的设置,都是默认的UTF-8 编码,所以没有任何问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。

2.3 InputStreamReader类

转换流java.io.InputStreamReader ,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

构造方法

InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。

InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流。

参数:InputStream in:读取文件中的字节

String charsetName:String charsetName

使用步骤:

1,创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称

2,使用OutputStreamWriter对象中的方法read,读取文件

3,释放资源

注意事项:构造方法中指定的编码名称要和文件的编码相同,否则乱码

2.4 OutputStreamWriter类

转换流java.io.OutputStreamWriter ,是Writer的子类(write里面的方法都可以使用),是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

OutputStreamWriter(OutputStream out) : 创建一个使用默认字符集的字符流。

OutputStreamWriter(OutputStream out, String charsetName) : 创建一个指定字符集的字符流。

参数 OutputStream out:字节输出流,可以用来写转换后的字节到文件中

String charsetName:指定的编码表名称,不区分大小写,不指定默认UTF-8

使用步骤:

1,创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称

2,使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)

3,使用OutputStreamWriter对象中的的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节写字节的过程)

4,释放资源

三 序列化

3.1 概述

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。

字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象 **

3.2 ObjectOutputStream类

java.io.ObjectOutputStream 类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。

构造方法 public ObjectOutputStream(OutputStream out): 创建一个指定OutputStream的ObjectOutputStream

注意事项:

序列化反序列化的时候,会抛出NotSertialzableEexception没有序列化异常,需要用过java.io.Serializable接口以启动其序列化功能,给类添加一个标记。

Serializable 接口也叫标记型接口,没有就会抛出异常

3.3 ObjectInputStream类

ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

构造方法 public ObjectInputStream(InputStream in): 创建一个指定InputStream的ObjectInputStream。

InputStream in:字节输入流

特有的成员方法:Object readObject()从ObjectInputStream读取对象

使用步骤:

1,创建ObjectInputStream对象,构造方法中传递字节输入流

2,使用ObjectInputStream对象中的方法readObject读取保存的文件

3,释放资源

注意:readObject方法声明可能抛出ClassNotFoundEexception(文件找不到),当不存在对象的class文件时抛出异常。

反序列化的前提:

1,类必须实现Serializable

2,必须存在类对应的class

另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException 异常。

发生这个异常的原因如下:

  1. 该类的序列版本号与从流中读取的类描述符的版本号不匹配

  2. 该类包含未知数据类型

  3. 该类没有可访问的无参数构造方法 ** 解决办法:用final修饰serialVersionUID 使用serialVersionUID 该版本号的目的在于验证序列化的对象和对应类是否版本匹配,设定序列号。

3.4 transient关键字

static关键字:(静态关键字):静态优先于非静态加载到内存中,被静态static修饰的成员变量不能被序列化,序列化的都是对象。

transient关键字(瞬态关键字):被transient修饰的成员变量,不能被序列化。

四 打印流

java.io.PrintStream :打印流

PrintStream特点:

1,只负责数据的输出,不负责数据的读取

2,与其他输出流不同,PrintStream永远不会抛出IOException

3,有特有的方法,print 方法和println

构造方法:

PrintStream(File file):输出目的地是一个文件

PrintStream(OutputStream out):输出目的地是一个字节输出流

PrintStream(String filaname):输出目的地是一个文件路径

PrintStream extends OutputStream 继承父类的成员方法

注意事项:

1,如果使用继承自父类的write方法写数据,那么查看数据的时候回查询编码表

2,如果使用自己特有的方法print 方法和println方法写数据,写的数据原样输出

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值