一、缓冲流

1、介绍

  缓冲流:不能直接作用在文件上,需要包一层,它是一种处理流。用于提高文件的读写效率。它在流的基础上对流的功能进行了增强。提高读写速度的原因:内部提供了一个缓冲区。缺省使用 8192 个字节(8Kb)的缓冲区 。
  源码示例:BufferedInputStream

1 public class BufferedInputStream extends FilterInputStream {
2 // 默认缓冲区的大小
3 private static int DEFAULT_BUFFER_SIZE = 8192;
4 }

  要求:先关闭外层的流,再关闭内层的流。而关闭外层流的同时,内层流也会自动的进行关闭。关于内层流的关闭,可以省略。

2、BufferedInputStream,BufferedOutputStream(字节流的缓冲区)

  代码示例:用字节流缓冲区处理非文本文件(图片,视频等)。缓冲流复制图片。

 1 // 文件:F:\\hello.jpg
2 public class Main {
3
4 public static void main(String[] args) {
5 try (// 造节点流
6 FileInputStream fis = new FileInputStream((new File("F:\\hello.jpg")));
7 FileOutputStream fos = new FileOutputStream(new File("F:\\hello_1.jpg"));
8 // 造缓冲流
9 BufferedInputStream bis = new BufferedInputStream(fis);
10 BufferedOutputStream bos = new BufferedOutputStream(fos);) {
11
12 byte[] buffer = new byte[1024];
13 int len;
14 while ((len = bis.read(buffer)) != -1) {
15 bos.write(buffer, 0, len);
16 }
17
18 // 刷新缓冲区.必须
19 // bos.flush();
20 } catch (Exception e) {
21 }
22 }
23 }
24
25 // 用于copy 3.64G 的文件花费 18.925s

3、BufferedReader、BufferedWriter(字符流的缓冲区)

  BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以指定缓冲区的大小,或者使用默认的大小。在大多数情况下,默认值就足够大了。
  字符读取流缓冲区,该缓冲区提供了一个一次读一行的方法readLine(),方便于对文本数据的获取。当返回null时,表示读到文件末尾。
  BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。可以指定缓冲区的大小,或者接受默认的大小。在大多数情况下,默认值就足够大了。
  该缓冲区中提供了一个跨平台的换行符:newLine()。
  代码示例:用字符流缓冲区处理文本文件。缓冲流复制文本文件。

 1 // 文件:F:\\hello.txt
2 // 内容:任意
3
4 // 方式一:会自动换行
5 public class Main {
6
7 public static void main(String[] args) {
8 try ( // 造节点流
9 FileReader fr = new FileReader(new File("F:\\hello.txt"));
10 FileWriter fw = new FileWriter(new File("F:\\hello_1.txt"));
11
12 // 造缓冲流
13 BufferedReader br = new BufferedReader(fr);
14 BufferedWriter bw = new BufferedWriter(fw);) {
15
16 // 使用char[]数组
17 char[] cbuf = new char[1024];
18 int len;
19 while ((len = br.read(cbuf)) != -1) {
20 bw.write(cbuf, 0, len);
21 }
22
23 // bw.flush();
24 } catch (Exception e) {
25 }
26 }
27 }
28
29
30 // 方式二:不会自动换行
31 public class Main {
32
33 public static void main(String[] args) {
34 try ( // 造节点流
35 FileReader fr = new FileReader(new File("F:\\hello.txt"));
36 FileWriter fw = new FileWriter(new File("F:\\hello_1.txt"));
37
38 // 造缓冲流
39 BufferedReader br = new BufferedReader(fr);
40 BufferedWriter bw = new BufferedWriter(fw);) {
41
42 // 使用readLine(),一次性读一行
43 String data;
44 while ((data = br.readLine()) != null) {
45 // data中不包含换行符,读一行写一行,不会自动换行.若想换行,可以:
46 // 方法一:
47 // bw.write(data + "\n");
48
49 // 方法二:
50 bw.write(data);
51 bw.newLine();
52 }
53
54 // bw.flush();
55 } catch (Exception e) {
56 }
57 }
58 }

4、装饰设计模式

  自定义的字符读取流缓冲区myReadLine(),将readLine()方法实现了一次。
  代码示例:

 1 class MyBufferedReader {
2 private final FileReader fileReader;
3
4 public MyBufferedReader(FileReader fileReader) {
5 this.fileReader = fileReader;
6 }
7
8 public String myReadLine() throws IOException {
9 StringBuilder builder = new StringBuilder();
10
11 int len;
12 while ((len = fileReader.read()) != -1) {
13 if (len == '\r') {
14 continue;
15 }
16 if (len == '\n') {
17 return builder.toString();
18 }
19
20 builder.append((char) len);
21 }
22
23 if (builder.length() != 0) {
24 return builder.toString();
25 }
26
27 return null;
28 }
29
30 public void myClose() {
31 try {
32 fileReader.close();
33 } catch (IOException e) {
34 e.printStackTrace();
35 }
36 }
37 }
38
39 // 注意关闭资源
40 // 文件:F:\\hello1.txt
41 // 内容:
42 我有a dream!
43 you need to have a dream!我有a dream!
44 you need to have a dream!
45 public class Main {
46 public static void main(String[] args) throws Exception {
47 MyBufferedReader reader = new MyBufferedReader(new FileReader(new File("F:\\hello1.txt")));
48
49 String temp;
50 while ((temp = reader.myReadLine()) != null) {
51 System.out.println(temp);
52 }
53
54 reader.myClose();
55 }
56 }
57
58 // 结果.打印正常

五、转换流

1、介绍

  转换流提供了在字节流和字符流之间的转换。
  InputStreamReader:将InputStream转换为Reader,实现将字节的输入流按指定字符集转换为字符的输入流。解码。
  OutputStreamWriter:将Writer转换为OutputStream,实现将字符的输出流按指定字符集转换为字节的输出流。编码。
  很多时候使用转换流来处理文件乱码问题。实现编和解码的功能。

2、InputStreamReader

  每次调用InputStreamReader中的一个read()方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。
  为了达到最高效率,可要考虑在InputStreamReader外套接一层BufferedReader。
  键盘录入的标准写法:BufferedReader in = new BufferedReader(new InputStreamReader(System.in))
  代码示例:读文件。字节流->字符流

 1 public class Main {
2
3 public static void main(String[] args) {
4 try (FileInputStream fis = new FileInputStream(new File("F:\\hello.txt"));
5 InputStreamReader isr = new InputStreamReader(fis, "UTF-8");) {
6
7 char[] cbuf = new char[1024];
8 int len;
9 while ((len = isr.read(cbuf)) != -1) {
10 String str = new String(cbuf, 0, len);
11 System.out.print(str);
12 }
13
14 } catch (Exception e) {
15 }
16 }
17 }

  代码示例:读键盘。缓冲流

 1 public class Main {
2
3 public static void main(String[] args) {
4 try (// 从标准键盘输入.
5 BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));) {
6
7 String line = null;
8 while ((line = reader.readLine()) != null) {
9 if ("over".equals(line)) {
10 return;
11 }
12 System.out.println(line);
13 }
14 } catch (Exception e) {
15 }
16 }
17 }

3、OutputStreamWriter

  每次调用write()方法都会导致在给定字符(或字符集)上调用编码转换器。在写入底层输出流之前,得到的这些字节将在缓冲区中累积。可以指定此缓冲区的大小,不过,默认的缓冲区对数用途来说已足够大。注意,传递给write()方法的字符没有缓冲。
  为了获得最高效率,可考虑在OutputStreamWriter外套接一层BufferedWriter。以避免频繁调用转换器。例:
  Writer out = new BufferedWriter(new OutputStreamWriter(System.out))
  代码示例:写文件。字符流->字节流

 1 public class Main {
2
3 public static void main(String[] args) {
4 try (FileInputStream fis = new FileInputStream(new File("F:\\hello.txt"));
5 FileOutputStream fos = new FileOutputStream(new File("F:\\hello_1.txt"));
6
7 InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
8 OutputStreamWriter osw = new OutputStreamWriter(fos, "gbk");) {
9
10 char[] cbuf = new char[1024];
11 int len;
12 while ((len = isr.read(cbuf)) != -1) {
13 osw.write(cbuf, 0, len);
14 }
15
16 isr.close();
17 osw.close();
18 } catch (Exception e) {
19 }
20 }
21 }

  代码示例:读\写键盘。缓冲流

 1 public class Main {
2
3 public static void main(String[] args) {
4 try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
5 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));) {
6
7 String line = null;
8 while ((line = reader.readLine()) != null) {
9 if ("over".equalsIgnoreCase(line)) {
10 break;
11 }
12 writer.write(line.toUpperCase());
13 writer.newLine(); // 换行
14 writer.flush();
15 }
16
17 reader.close();
18 writer.close();
19 } catch (Exception e) {
20 }
21 }
22 }

4、字符集

  ASCII:美国标准信息交换码。用一个字节的7位可以表示。
  ISO8859-1:拉丁码表。欧洲码表。用一个字节的8位表示。
  GB2312:中国的中文编码表。最多两个字节编码所有字符
  GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码
  Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的字符码。所有的文字都用两个字节来表示。
  UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

Java基础(八)——IO流2_缓冲流、转换流的更多相关文章

  1. 黑马程序员——JAVA基础之IO流缓冲区,转换流,字节流

    ------- android培训.java培训.期待与您交流! ---------- 字符流的缓冲区        缓冲区的出现提高了对数据的读写效率. 对应类 •  BufferedWriter ...

  2. java基础之IO流(二)之字符流

    java基础之IO流(二)之字符流 字符流,顾名思义,它是以字符为数据处理单元的流对象,那么字符流和字节流之间的关系又是如何呢? 字符流可以理解为是字节流+字符编码集额一种封装与抽象,专门设计用来读写 ...

  3. Java基础之IO流整理

    Java基础之IO流 Java IO流使用装饰器设计模式,因此如果不能理清其中的关系的话很容易把各种流搞混,此文将简单的几个流进行梳理,后序遇见新的流会继续更新(本文下方还附有xmind文件链接) 抽 ...

  4. Java基础:IO流之字节流和字符流

    1. 流的概念 流(stream)的概念源于UNIX中管道(pipe)的概念.在UNIX中,管道是一条不间断的字节流,用来实现程序或进程间的通信,或读写外围设备.外部文件等. 一个流,必有源端和目的端 ...

  5. java基础之IO流(一)字节流

    java基础之IO流(一)之字节流 IO流体系太大,涉及到的各种流对象,我觉得很有必要总结一下. 那什么是IO流,IO代表Input.Output,而流就是原始数据源与目标媒介的数据传输的一种抽象.典 ...

  6. day1 java基础回顾-IO流

    IO流的分类 注:这几个类都是抽象类. IO解决问题: 解决设备与设备之间 的数据传输问题. 比如: 硬盘--->内存 内存----->硬盘 字节流: 输入字节流:---------| I ...

  7. java基础之io流总结四:字符流读写

    字符流读写只适用于字符文件. 基本字符流(转换流)读写文件 转换流本身是字符流,但是实例化的时候传进去的是一个字节流,所以叫做转换流 InputStreamReader isr = new Input ...

  8. java IO流 (五) 转换流的使用 以及编码集

    转换流的使用 1.转换流涉及到的类:属于字符流InputStreamReader:将一个字节的输入流转换为字符的输入流解码:字节.字节数组 --->字符数组.字符串 OutputStreamWr ...

  9. JAVA之旅(二十七)——字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律

    JAVA之旅(二十七)--字节流的缓冲区,拷贝mp3,自定义字节流缓冲区,读取键盘录入,转换流InputStreamReader,写入转换流,流操作的规律 我们继续来聊聊I/O 一.字节流的缓冲区 这 ...

  10. Java基础学习 —— io

    /** 解决数据与数据之间的传输问题. 字节流: 输入字节流: -------| InputStream 所有输入字节流的基类.抽象类. -----------| FileInputStream 读取 ...

随机推荐

  1. 商业爬虫学习笔记day8-------json的使用

    一. 简介 JSON,全称为JavaScript Object Notation(JavaScript对象标记),它通过对象和数组的组合来表示数据,是一种轻量级的数据交换格式.它基于 ECMAScri ...

  2. nodeJs,Express中间件是什么与常见中间件

    中间件的功能和分类 中间件的本质就是一个函数,在收到请求和返回相应的过程中做一些我们想做的事情.Express文档中对它的作用是这么描述的: 执行任何代码.修改请求和响应对象.终结请求-响应循环.调用 ...

  3. Java实现单链表的增删查改及逆置打印

    //所提供的接口 LinkList.java package Struct; public interface LinkList {//判断链表为空public boolean linkListIsE ...

  4. OpenStack之七: compute服务(端口8774)

    注意此处的bug,参考o版 官网地址 https://docs.openstack.org/nova/stein/install/controller-install-rdo.html 控制端配置 # ...

  5. 观察者模式之spring事件机制

    ddsspring中的事件机制使用到设计模式中的观察者模式 ,观察者模式有两个概念,1.观察者.被观察者.2.被观察者做出相应得动作,观察者能接收到.不分析设计模式,学习下spring中的事件机制实际 ...

  6. shell脚本 awk实现实时监控网卡流量

    一.简介 通过第3方工具获得网卡流量,这个大家一定很清楚.其实通过脚本一样可以实现效果.下面是我个人工作中整理的数据.以下是shell脚本统计网卡流量. 现原理: cat /proc/net/dev ...

  7. python获取命令行传参的两种种常用方法argparse解析getopt 模块解析

    方法一:argparse解析 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # @Time: 2020/5/20 10:38 # @Author:zhan ...

  8. 当ligerui的grid出现固定列与非固定列不在同一水平线上时,改怎么处理

    当ligerui的grid出现固定列与非固定列不在同一水平线上时,如下图所示: 此时可以增加fixedCellHeight:false属性进行解决.这个属性在IE上不起作用,那么该怎么处理,可以这样处 ...

  9. JAVA实现智能分词(通过文章标题生成tag标签)

    导入jar包 IKAnalyzer2012_u6.jar下载链接:https://pan.xunlew.com/s86789 maven <dependency> <groupId& ...

  10. 出现线上bug,测试人能做些什么?

    测试奇谭,BUG不见. 大家好,我是谭叔. 一提到线上问题,很多测试小白要么"原则性"恐惧,要么憨憨如也,不知如何下手. 本篇文章,我再细化下这道常见的面试题,跟大家捋捋发生线上问 ...