IO介绍&字节流

  • IO流概述及分类

IO流简介

通过昨天的学习,大家都能够使用File类实现对文件和文件夹的一些操作了;但是还不能操作文件里面的数据;

要操作一个文件里面的数据,就要使用IO流来实现;

什么是IO流呢?

前面简单给大家说过IO的概念,IO就是input和output的缩写,表示数据相对于程序内存的输入和输出操作;

将数据输入内存,以及将数据输出内存,都需要专门的对象来操作;这些负责具体的输入或输出数据的对象,就是IO流对象;


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节


在计算机领域,只要不在同一个程序的内存空间,数据的移动都需要通过IO流来实现;

  • IO流分类

针对不同的输入和输出数据的需求,java提供了不同的IO流;为了更方便的学习掌握它们,可以根据不同的特点给它们进行分类:按照IO操作中数据的流向,可将IO流分为输入流和输出流(输入和输出,是相对于内存而言的):

输入流:将数据从程序之外的地方读进程序内存
输出流:将数据从程序内存输出到程序之外的地方;

按照IO操作中数据的类型,可将IO流分为字节流和字符流;

字节流:读写的数据都是字节数据;
字符流:读写的数据都是字符数据;

问题:什么是字节数据和字符数据?

字节数据:在计算机底层,所有数据都是使用二进制数字保存的;每八个二进制位,就是一个字节数据;
字符数据:一个文件使用记事本打开,如果里面的内容可以看懂,文件中的数据就是字符数据(word文档里面不是字符数据);

字符数据和字节数据的关系:字符底层也是使用字节数据保存的;根据不同的编码表的规则,一个字符可以由不同的字节数据表示;


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_02


问题:什么时候用字节流?什么时候用字符流?

所有文件都可以使用字节流;

如果一个文件里面是字符数据,应该使用字符流;

字节流和字符流也有输入和输出之分,可以再将它们进一步细分为四个类别:

字节输入流:

最高父类:InputStream;
子类:XxxInputStream;

字节输出流:

最高父类:OutputStream;
子类:XxxOutputStream;

字符输入流:

最高父类:Reader;
子类:XxxReader;

字符输出流:

最高父类:Writer;
子类:XxxWriter;

字节流

字节输入流

InputStream介绍


java 删除 换行符 java删除最后一个换行符_java换行符_03


总结:

  1. InputStream在http://Java.io包中,使用需要手动导包;
  2. InputStream是我们Java中所有字节输入流的最高父类;
  3. InputStrean是一个抽象类,不能直接用它创建对象,而是应该使用它的儿子;


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_04


InputStream定义的读取数据的方法,必须掌握:


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_05


我们每次使用IO流之后,都需要调用这个函数进行关流,释放资源;


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_06

https://www.zhihu.com/video/1072881237848444928



FileInputStream介绍


java 删除 换行符 java删除最后一个换行符_java换行符_07


java 删除 换行符 java删除最后一个换行符_java换行符_08


说明:

使用FileInputstream类创建对象,必须指定要读取的那个文件;因为这个类就是专门用来从文件中读取数据的,所以必须告诉他要关联到哪一个文件上;


java 删除 换行符 java删除最后一个换行符_java换行符_09

https://www.zhihu.com/video/1072881358300495872



使用FileInputStream读取文件数据

使用这个类读取文件中数据的步骤:

  1. 创建一个FileInputStream对象,关联到要读的文件;
  2. 调用这个对象的读取功能,读取数据,使用变量接受;
  3. 读完,关闭流,释放资源;

原始文件内容:


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_10


按字节读取:


java 删除 换行符 java删除最后一个换行符_java换行符_11


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_12


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_13


按照字节数组读取数据:


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_14


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_15


一次读取指定个数的字节,放到指定数组中:


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_16


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_17


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_18


java 删除 换行符 java删除最后一个换行符_java换行符_19

https://www.zhihu.com/video/1072881608251711488



FileInputStream使用注意事项

  • 一个文件字节输入流读文件,读完就不能再读;
  • 文件输入流不能关联到一个不存在的文件上;


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_20


  • 文件输入流不能关联到一个文件夹上;


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_21


  • 文件输入流不能关联到被系统使用的文件上;


java 删除 换行符 java删除最后一个换行符_java换行符_22


总结:使用字节输入流读取文件中数据的步骤


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_23

https://www.zhihu.com/video/1072882136347897856


步骤:

  1. 创建一个文件字节输入流对象,关联到需要读取数据的文件上;
  2. 定义int变量或byte数组,用于接收读取到的字节数据;
  3. 循环读取数据,如果读取方法返回的结果是-1,就表示数据已经读取完毕;
  4. 关闭输入流对象

代码模板


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_24


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_25

https://www.zhihu.com/video/1072882417643307008


字节输出流

OutputStream介绍


java 删除 换行符 java删除最后一个换行符_java换行符_26


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_27


FileOutputStream介绍


java 删除 换行符 java删除最后一个换行符_java换行符_28


总结:

  1. 这个类在http://java.io包中,使用需要手动导包;
  2. 这个类可以将字节数据写出到文件中;
  3. 这个类的对象关联的目标文件可以不存在,如果不存在,这个对象会自动创建(但是能否成功创建,由操作系统决定);
  4. 这个类只能写出字节数据;如果要写出字符数据,应该使用字符输出流;


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_29


java 删除 换行符 java删除最后一个换行符_java换行符_30


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_31


使用FileOutputStream向文件写出数据

使用字节输出流向文件中写出数据的步骤:

  1. 创建FileOutputStream对象,关联到要写的文件;
  2. 调用函数向文件中写数据;
  3. 关闭流;

演示输出一个字节数据:


java 删除 换行符 java删除最后一个换行符_java换行符_32


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_33


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_34


演示输出一个字节数组:


java 删除 换行符 java删除最后一个换行符_java换行符_35


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_36


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_37


演示输出一个字节数组中的一部分:


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_38


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_39


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_40


java 删除 换行符 java删除最后一个换行符_java换行符_41

https://www.zhihu.com/video/1073317466557583360



追加数据到文件结尾和输出换行

追加数据到文件结尾


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_42


向文件中输出换行

方法一:需要输出换行的地方输出换行符:n;


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_43


换行符n在windows操作系统里面没问题,但是不表示在其他操作系统中也可以正常工作;

最好的办法,直接获取操作系统中的换行符

方法二:使用System类中的方法,获取和平台有关的换行符;


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_44


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_45


输出换行,推荐使用这种方式;


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_46

https://www.zhihu.com/video/1073317654189625344



追加数据和换行练习

需求:书写一个日志工具类,可以将接受到的数据写入一个日志文件。


/**


需求:将一个磁盘中的一个文件复制到另一个磁盘中;

文件复制的原理:


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_47


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_48

https://www.zhihu.com/video/1073317930808344576



高效字节流:缓冲字节流

字节流的弊端:

字节流速度比较慢,因为每一次读写数据, 都要去操作硬盘上的文件;
字节流对数据的读写操作,都是实时和硬盘上的文件进行操作;
为了解决这个问题,提高IO读写数据的效率,java中提供了字节流缓冲区;

字节流缓冲区原理


java 删除 换行符 java删除最后一个换行符_图片流写出 并带数据_49


结论:

缓冲区流能够提高效率的原因, 就是缓冲区流中有一个缓存空间,一般的io操作都是操作缓存空间的,减少了对硬盘的直接操作,所以能够提高效率;

缓冲字节流介绍

字节输入流缓冲区: BufferedInputStream;


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_50


java 删除 换行符 java删除最后一个换行符_java 删除 换行符_51


缓冲区中默认缓冲数组的大小是8192字节;可以通过构造函数手动修改;

输入字节流缓冲区的作用主要是将数据读进缓存,读数据的方法InputStream一样;

字节输出流缓冲区:BufferedOutputStream;


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_52


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_53


java 删除 换行符 java删除最后一个换行符_java 去掉最后一个换行符_54

https://www.zhihu.com/video/1073318064950640640



字节流缓冲区使用演示

用四种方式复制文件,对比效率

四种文件复制的方式:

普通字节流,每次读一个字节
普通字节流,每次读一个字节数组
缓冲字节流,每次读一个字节
缓冲字节流,每次读一个字节数组

代码:


public


结果:


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_55


结论:

按照效率从高到底排序:

字节流一次读写一个字节数组
字节流缓冲区一次读写一个字节数组;
字节流缓冲区一次读写一个字节数据;
字节流一次读写一个字节数据(开发中不要用这种)

实际开发中,一般使用字节流缓冲区或者字节流按照数组读写数据都可以,这二者速度相差不大;当读写数据的数组一样大时,字节流比缓冲区还稍微快一点;


java 删除 换行符 java删除最后一个换行符_java 换行符占几个字节_56