一、缓冲流

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. How is Quality Score Calculated?

    Google determines Quality Score slightly differently for each of the different advertising networks ...

  2. jdk1.6,1.7,1.8解压版无需安装(64位)

    1.java SE 1.6各个版本 jdk http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads ...

  3. oracle keep

    语法: min | max(column1) keep (dense_rank first | last order by column2) over (partion by column3); -- ...

  4. 【Linux】【Services】【SaaS】Docker+kubernetes(13. 部署Jenkins/Maven实现代码自动化发布)

    1. 简介 Jenkins: 官方网站:https://jenkins.io/ 下载地址:https://jenkins.io/download/ war包下载:http://mirrors.jenk ...

  5. I/O流之字节流

    在程序中所有的数据都是以流的形式进行传输或保存的,程序需要数据时要使用输入流读取数据,而当程序需要将一些数据保存起来时,就要使用输出流完成对于操作文件内容,要进行文件内容的操作就需要通过Java提供的 ...

  6. Java如何生成随机数 - Random、ThreadLocalRandom、SecureRandom

    Java7 的Random伪随机数和线程安全的ThreadLocalRandom 一.Random伪随机数: Random 类专门用于生成一个伪随机数,它有两个构造器: 一个构造器使用默认的种子(以当 ...

  7. gogs报错解决合集

    目录 一.在组织中添加成员,一直显示普通用户 一.在组织中添加成员,一直显示普通用户 组织是公司,团队是公司中的不同队伍.例如A团队设置为加入就有管理员权限,那加入就有管理员. 但在组织成员那一栏中加 ...

  8. CVE 2021-44228 Log4j-2命令执行复现及分析

    12月11日:Apache Log4j2官方发布了2.15.0 版本,以修复CVE-2021-44228.虽然 2.15.0 版本解决了Message Lookups功能和JNDI 访问方式的问题,但 ...

  9. .NET6中一些常用组件的配置及使用记录,持续更新中。。。

    NET6App 介绍 .NET 6的CoreApp框架,用来学习.NET6的一些变动和新特性,使用EFCore,等一系列组件的运用,每个用单独的文档篇章记录,持续更新文档哦. 如果对您有帮助,点击右上 ...

  10. JAVA获取昨天、今天、明天等日期

    /** * 获取明天的日期字符串 * @return */ public static String tomorrowDateStr(){ Date date=new Date();//取时间 Cal ...