一、概述

1、介绍

  I/O是 Input/Output 的缩写,IO流用来处理设备之间的数据传输,如读/写文件,网络通讯等。Java对数据的操作是通过流的方式进行。java.io 包下提供了各种"流"类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。
  输入input:读取外部数据(磁盘、光盘等存储设备的数据)到程序(内存)中。
  输出output:将程序(内存)数据输出到磁盘、光盘等存储设备中。

2、分类

  按操作数据单位不同分为: 字节流 (8 bit),字符流 (16 bit)。
  按数据流的流向不同分为: 输入流,输出流。
  按流的角色的不同分为: 节点流(文件流),处理流。

  节点流(文件流):直接作用在文件上,从数据源或目的地读写数据。
  处理流:不直接作用在文件上,不直接连接到数据源或目的地,而是"连接"在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。

  节点流:

  处理流:

3、IO流体系

  四个顶层的抽象基类。

  由这四个类派生出来的子类名称都是以其父类作为子类名的后缀。例:InputStream的子类FileInputStream,Reader的子类FileReader。
  IO流的体系如下:重点掌握高亮部分。

  【访问文件】是节点流(文件流),其他(除了抽象基类)都是处理流。

二、字符流

1、FileReader(输入)

  用来读取字符文件的便捷类。此类的构造方法假定默认字符编码和默认字节缓冲区大小都是适当的。要自己指定这些值,可以先在FileInputStream上构造一个InputStream。
  read():一次读一个字符,指针会指向下一个字符。读到末尾返回-1。
  代码示例:读文件

 1 // 文件:F:\\hello.txt
2 // 内容:helloworld123中国人1
3 public class Main {
4 public static void main(String[] args) {
5 try (FileReader fr = new FileReader(new File("F:\\hello.txt"));) {
6 int data;
7 while ((data = fr.read()) != -1) {
8 System.out.print((char) data);
9 }
10 } catch (Exception e) {
11 }
12 }
13 }
14
15 // 结果
16 helloworld123中国人的

  read(char[] buff):一次读 buff.length 个字符,返回读取的个数。读到末尾返回-1。
  代码示例:错误的写法

 1 // 文件:F:\\hello.txt
2 // 内容:helloworld123中国人1
3 public class Main {
4 public static void main(String[] args) {
5 try (FileReader fr = new FileReader(new File("F:\\hello.txt"));) {
6 char[] buff = new char[5];
7 int len;
8
9 while ((len = fr.read(buff)) != -1) {
10 // 方式一:
11 for (char c : buff) {
12 System.out.print(c);
13 }
14
15 // 方式二:
16 // String str = new String(buff);
17 // System.out.print(str);
18 }
19 } catch (Exception e) {
20 }
21 }
22 }
23
24 // 结果.方式一 和 方式二都是
25 helloworld123中国人13中国

  代码示例:正确的写法

 1 // 文件:F:\\hello.txt
2 // 内容:helloworld123中国人1
3 public class Main {
4 public static void main(String[] args) {
5 try (FileReader fr = new FileReader(new File("F:\\hello.txt"));) {
6 char[] buff = new char[5];
7 int len;
8
9 while ((len = fr.read(buff)) != -1) {
10 // 方式一:
11 for (int i = 0; i < len; i++) {
12 System.out.print(buff[i]);
13 }
14
15 // 方式二:从 buff 的下标 0 开始取字符,取 len 个
16 // String str = new String(buff, 0, len);
17 // System.out.print(str);
18 }
19 } catch (Exception e) {
20 }
21 }
22 }
23
24 // 结果
25 helloworld123中国人1

  深刻理解 read(char[] buff) 方法:一次读进 buff.length 个字符,打印。读取下次的时候,上次读取的字符其实还在字符数组中,所以最后"人1"只覆盖了上一次的前两个字符,使得最后字符数组里是"人 1 3 中 国"。

2、FileWriter(输出)

  构造方法必须明确被操作的文件,若指定目录下不存在,会被创建;若存在,会被覆盖。相关API如下:

  new FileWriter(String fileName):在指定目录下创建
  new FileWirter(String fileName, boolean append):是否为追加数据
  void write(String int):重载,将字符串写入到流中
  void write(char[] buff):写入字符数组
  void wirte(char[] buff, int off, int len):写入字符数组的某一部分
  void flush():刷新流,流可以继续使用
  void close():先刷新流,关闭流,流不可以继续使用

  注:通过write()写入换行用 \r\n,对应的字节为 13 10

  代码示例:写文件

 1 public class Main {
2 public static void main(String[] args) {
3 // 默认不追加,覆盖原有的文件内容
4 try (FileWriter fw = new FileWriter(new File("F:\\hello.txt"));) {
5
6 // 表示在原有文件内容的基础上追加
7 // FileWriter fw = new FileWriter(new File("F:\\hello.txt"), true);
8 fw.write("我有a dream!\n");
9 fw.write("you need to have a dream!");
10
11 // fw.flush();
12 } catch (Exception e) {
13 }
14 }
15 }

3、复制文件

  代码示例:字符流复制文本文件

 1 public class Main {
2 public static void main(String[] args) {
3 try (FileReader fr = new FileReader(new File("F:\\hello.txt"));
4 FileWriter fw = new FileWriter(new File("F:\\hello_copy.txt"));) {
5
6 char[] buff = new char[5];
7 int len;
8
9 // 一次读出len个字符到buff.
10 while ((len = fr.read(buff)) != -1) {
11 fw.write(buff, 0, len);
12 fw.flush();
13 }
14 } catch (Exception e) {
15 }
16 }
17 }

  注:不能使用字符流来处理图片,视频等字节数据。

三、字节流

1、FileInputStream(输入)

  基本用法和字符流一样。
  代码示例:读文件,可能出现乱码。

 1 // 文件:F:\\hello.txt
2 // 内容:helloworld123中国人1
3 public class Main {
4 public static void main(String[] args) {
5 try (FileInputStream fis = new FileInputStream(new File("F:\\hello.txt"));) {
6 // fis.available():返回文件字节数
7 byte[] buffer = new byte[5];
8 int len;
9
10 // 按字节来读取
11 while ((len = fis.read(buffer)) != -1) {
12 String str = new String(buffer, 0, len);
13 System.out.print(str);
14 }
15 } catch (Exception e) {
16
17 }
18 }
19 }
20
21 // 结果,有乱码.原因就是一个汉字占两字节,被分割了.
22 helloworld123��国���1

2、FileOutputStream(输出)

  基本用法和字符流一样,不同于在写入时不需要flush()。

  void write(int b):一次写入一个字节
  void write(byte[] b):写入一个字节数组
  void write(byte[] b, int off, int len):写入一个字节数组,off开始,len字节数

  代码示例:写文件

 1 public class Main {
2 public static void main(String[] args) {
3 try (FileOutputStream fos = new FileOutputStream(new File("F:\\hello.txt"));) {
4
5 fos.write("我有a dream!\n".getBytes());
6 fos.write("you need to have a dream!".getBytes());
7
8 } catch (Exception e) {
9 }
10 }
11 }
12
13 // 结果,有乱码.
14 鎴戞湁a dream!
15 you need to have a dream!

  总结:因为一个汉字占两个字节。所以,
  字符流,适用于读写文本文件。不适用于字节流,容易出现乱码。
  字节流,适用于读写二进制文件,比如图片,音频,视频等。

3、复制文件

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

 1 // 文件:F:\\hello.PNG
2 public class Main {
3 public static void main(String[] args) {
4 try (FileInputStream fis = new FileInputStream(new File("F:\\hello.PNG"));
5 FileOutputStream fos = new FileOutputStream(new File("F:\\hello_1.PNG"));) {
6
7 byte[] buffer = new byte[5];
8 int len;
9
10 // 一次性读一个 len 个字节到buffer. len <= buffer
11 while ((len = fis.read(buffer)) != -1) {
12 fos.write(buffer, 0, len);
13 }
14 } catch (Exception e) {
15 }
16 }
17 }
18
19 // 此代码用于复制 3.64G 的文件花费 56.574s

Java基础(八)——IO流1_字节流、字符流的更多相关文章

  1. Java基础之IO流学习总结

    Java流操作有关的类或接口: Java流类图结构: 流的概念和作用 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象.即数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输 ...

  2. IO流(字节流,字符流,缓冲流)

    一:IO流的分类(组织架构) 根据处理数据类型的不同分为:字节流和字符流 根据数据流向不同分为:输入流和输出流   这么庞大的体系里面,常用的就那么几个,我们把它们抽取出来,如下图:   二:字符字节 ...

  3. Java基础---IO(一)---IO流概述、字符流、字节流、流操作规律

    第一讲     IO概述 概述 1.IO流:即InputOutput的缩写. 2.特点: 1)IO流用来处理设备间的数据传输. 2)Java对数据的操作是通过流的方式. 3)Java用于操作流的对象都 ...

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

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

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

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

  6. -1-4 java io java流 常用流 分类 File类 文件 字节流 字符流 缓冲流 内存操作流 合并序列流

      File类 •文件和目录路径名的抽象表示形式 构造方法 •public File(String pathname) •public File(String parent,Stringchild) ...

  7. java基础46 IO流技术(输出字符流/缓冲输出字符流)

    一.输出字符流 1.1.输出字符流体系 --------| Writer:输出字符流的基类(抽象类)  ----------| FileWriter:向文件输出数据输出字符流(把程序中的数据写到硬盘中 ...

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

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

  9. Java基础之IO流整理

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

  10. Java IO 转换流 字节转字符流

    Java IO 转换流 字节转字符流 @author ixenos 字节流 输入字节流:---------| InputStream 所有输入字节流的基类. 抽象类.------------| Fil ...

随机推荐

  1. 【模板】二分图最大匹配(匈牙利算法)/洛谷P3386

    题目链接 https://www.luogu.com.cn/problem/P3386 题目大意 给定一个二分图,其左部点的个数为 \(n\),右部点的个数为 \(m\),边数为 \(e\),求其最大 ...

  2. keybd_event模拟键盘按键,mouse_event怎么用

    从 模仿UP主,用Python实现一个弹幕控制的直播间! - 蛮三刀酱 - 博客园 (cnblogs.com) 知道了 PyAutoGUI: * Moving the mouse and clicki ...

  3. A Child's History of England.19

    The King was at first as blind and stubborn as kings usually have been whensoever [每当] they have bee ...

  4. HTML5 基础内容(元素/属性/格式化)

    HTML基础 1.HTML元素 1.1 元素指的是开始标签到结束标签的所有代码. 1.2 元素的内容是开始标签与结束标签之间的内容. 1.3大多数HTML元素可用有属性. 1.4标签可以拥有属性为元素 ...

  5. 基于 vue-cli 的 lib-flexible 适配

    基于 vue-cli3.0 的 lib-flexible 适配方案 第一步:下载安装相关依赖 第二步:创建 vue.config.js 文件并配置 第三步:在 main.js 中引入 lib-flex ...

  6. iOS-调用系统的短信和发送邮件功能,实现短信分享和邮件分享

    一.邮件分享 1.iOS系统自带邮件设置邮箱(此处以QQ邮箱为例)(http://jingyan.baidu.com/album/6181c3e084cb7d152ef153b5.html?picin ...

  7. springboot+vue脚手架使用nginx前后端分离

    1.vue配置 /** * * 相对于该配置的nginx服务器请参考nginx配置文件 * */ module.exports = { // 基本路径 publicPath: '/', // 输出文件 ...

  8. 【Spring Framework】Spring入门教程(八)Spring的事务管理

    事务是什么? 事务:指单个逻辑操作单元的集合. 在操作数据库时(增删改),如果同时操作多次数据,我们从业务希望,要么全部成功,要么全部失败.这种情况称为事务处理. 例如:A转账给B. 第一步,扣除A君 ...

  9. 【Linux】【Basis】Grub

    GRUB(Boot Loader):   1. grub: GRand Unified Bootloader grub 0.x: grub legacy grub 1.x: grub2   2. gr ...

  10. PHP安装sqlsrv扩展( Centos系统、或宝塔面板)

    最近新安装了一台Centos服务器, 由于软件使用PHP + sqlserver , 因此需要给PHP安装一个sqlsrv扩展, 虽然这个扩展自己也安装过很多次了,但是从来都没有记录下来过,导致偶尔还 ...