一、缓冲流

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. Node.js 概述

    JavaScript 标准参考教程(alpha) 草稿二:Node.js Node.js 概述 GitHub TOP Node.js 概述 来自<JavaScript 标准参考教程(alpha) ...

  2. 【swift】复制后,为Xcode工程项目重新修改名称

    感谢,参考了另一篇博客:https://www.jianshu.com/p/abf10c9609ef 我做了一些修改,和自己遇到的情况 我用的是繁体的mac,所以下面图片内,鼠标右键点出来的文字(丢到 ...

  3. Ruby Gems更换淘宝源方法

    官方的 Rubygems 源由于有些资源放在 Amazon S3 上面,所以有时会抽风,在 Linux 下我用 proxychains gem install xxx 实现了指定程序实行 Shadow ...

  4. spring cloud config center Git SSH configuration

    Git SSH configuration using properties By default, the JGit library used by Spring Cloud Config Serv ...

  5. Java RestTemplate传递参数

    最近使用Spring 的 RestTemplate 工具类请求接口的时候发现参数传递的一个坑,也就是当我们把参数封装在Map里面的时候,Map 的类型选择. 使用RestTemplate post请求 ...

  6. Linux centos7 安装.net 环境

    其实在linux 下安装.net 环境并不复杂,但最近遇到的服务器没有外网,比较坑很多依赖都没有,记录下这次的安装过程. 一开始以为是服务器没有外网,后来发现是服务器没有配置dns,于是配置dns 第 ...

  7. Java基础语法与流程控制

    Java基础语法与流程控制 跟着狂神学Java的第二天O(∩_∩)O~,养成一个总结的习惯 志同道合的小伙伴可以一起学习狂神的视频 本节地址:https://www.kuangstudy.com/co ...

  8. python3约瑟夫环问题

    问题描述:n个人围成一个圈,从第一个人开始数1,数到第k个出局,然后下一个人继续从1数,求出局人编号 思路:将所有人编号放到数组里,一个人出局后,下一个人加上k对数组长度求余,得出下一个要删除的编号. ...

  9. 云原生应用管理,像管理手机APP一样管理企业应用

    我们在使用智能手机的时候,手机APP从应用市场一键安装,安装好即点即用,当有新版本一键升级,如果不想用了长按图标删除,整个过程非常简单,小朋友都能熟练掌握.而对于企业应用,由于结构复杂.可用性要求高. ...

  10. JavaScript中的NaN

    论装逼我只服NaN 首先这逼自己都不愿意等于自己 console.log(NaN == NaN); // false 这逼够嫌弃自己的 其次这逼本身的意思是非数字就是NaN 然鹅typeof NaN结 ...