前言
Java通过File对象获取和表示文件,通过I/O对象获取、写出数据,完成数据的传输。
Java的IO流体系虽然很庞大,但是每一种IO流都有其自身特点和特定的使用场景;
一、File类
数据不能一直存于内存中,终究需要落地、持久化保存到硬盘上。
无论是从硬盘文件中读取数据或者将内存中的数据持久化保存到硬盘文件,都离不开文件。
在Java中一切皆对象,计算机上的文件也可以使用Java中的一个对象来表示,这个对象所在的类就是java.io.File类。
二、数据流
在Java中通过1个相关I/O流对象绑定1个File对象的形式创建流对象,通过流对象的方法,进行文件的读/写操作,完内存到硬盘之间的数据传输。
//FileOutputStream(File对象):字节流绑定了1个文件对象 FileOutputStream fos=new FileOutputStream(new File("chapter-11-IO\\test\\zhanggen.txt")); fos.close();
1.什么是数据流?
河床上有水流、高速公路上有车流,互联网上正在高速传输的数据叫数据流,流是一种抽象的概念,是对数据传输的总称
以上我们可通过Java的1个对象表示文件;
文件存在之后就需要对文件中保存的数据,进行读/写的操作。
文件的读/写操作,本质上是让数据像流水一样,从某个节点 流向 另一个节点 ,我们称之为数据传输;
数据的传输看成是一种数据的流动,数据传输过程中流动的数据称为数据流;
数据流流是一种抽象的概念:是对数据传输的总称
2.什么是I/O
以程序为中心,我们从外部数据源(文件、数据库)中读取外部数据到内存称之为Input;读
以程序为中心,我们处理完内存中数据,持久化到硬盘或者数据称之为Output; 写
以上2个动作我们统称为IO,也就是Input和Output这2个单词的缩写。
3.输入/出流
流:指的是传输过程中数据流
输入流:程序通过输入流,把数据输入到内存,进行处理;
输出流:程序通过输出流,把数据输出到硬盘,进行持久化;
4.IO流的种类
字节流: 万流之母,字节流中传输的二进制数据(以下所有数据流的底层都是驱动字节流进行数据传输)。
缓冲字节流: 给字节流设置缓冲/缓存,提高字节流的传输效率。
字符流: 基于Unicode(万国码)对包含中文+英文的数据进行UTF-8编码时,1个英文字母占1个字节,1个汉字占3个字节,字节流本身无法对1个数据进行精确分割和读取。
缓冲字符流: 设置字符流缓冲/缓存,提高字符流的传输效率。
序列化流 : 把Java中对象数据序列化存储到硬盘上。
在Java中以上5类流,都可以通过相关类的构造方法创建出流对象,再通过流对象的方法,完成文件数据 的读和写;
三、字节流
字节流是万流之母,所有流的本质就是驱动字节流完成数据传输;
使用字节流(FileInputStream,FileOutputStream)可以读取非文本信息,例如图片、声音、视频、图片等二进制信息。
1.FileInputStream 字节输入流
FileInputStream fis = new FileInputStream(new File("chapter-11-IO\\test\\a.txt"));
2.FileOutputStream字节输入流
FileOutputStream fos = new FileOutputStream(new File("chapter-11-IO\\test\\a.txt"));
四、字节缓冲流
给字节流设置缓冲/缓存,提高字节流的传输效率。
1.BufferedInputStream 缓冲字节输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("chapter-11-IO\\test\\a.txt")));
2.BufferedOutputStream 缓冲字节输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("chapter-11-IO\\test\\a.txt")));
五、字符流
字节流无法读取文本文件中的字符内容;
GBK和Unicode码表都向下兼容了ASCII码表;
在Uicode码表中:1个英文字母使用8位表示( 存储到内存/硬盘时占1个字节),1个汉字使用24位表示( 存储到内存/硬盘时占3个字节)
在GBK码表中: 1个英文字母使用8位表示( 存储到内存/硬盘时占1个字节),1个汉字使用16位表示( 存储到内存/硬盘时占2个字节)
如果使用UTF-8对中文数据编码,使用GBK对中文数据解码,或是使用GBK对中文数据编码,使用UTF-8对中文数据解码。
因为表示中文汉字和英文字母的字节长度单位不一致,之间度取字节流数据,无法按照一个固定的字节长度单位对包含英文+汉字的字符内容数据流进行正确分割(解码) ,导致乱码问题;
字符流=码表+字节流, 字符流可以根据指定的码表,对文本文件中的字符进行写入和读取操作。
1.InputStreamReader
InputStreamReader isr = new InputStreamReader(new FileInputStream(new File("chapter-12-IO\\c.txt")), "GBK");
2.OutputStreamWriter
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(new File("chapter-12-IO\\c.txt")), "GBK");
六、快捷字符流
其实读取数据时我们基本会使用一种默认的编码方式,不需要指定编/解码方式,快捷字符流是字符流的快速实现方式。
1.FileReader快捷字符输入流
FileReader fr = new FileReader(new File(oldfileName));
2.FileWriter快捷字符输出流
FileWriter fw=new FileWriter(oldfileName);
七、字符缓冲流
字符流缓冲流,可以对字符流和快捷字符流设置缓冲、缓存,提升字符流和字符快捷流的传输效率。
1.BufferedReader 缓冲字符输入流
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(oldfileName))));
2. BufferedWriter 缓冲字符输出流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(newfileName))));
八、序列化流
序列化流可以把对象这种结构化的数据保存到文件中,还能从文件中加载对象到程序中使用;
1.对象输入流 ObjectInputStream
ObjectInputStream ois= new ObjectInputStream(new FileInputStream(new File(fileName)));
2.对象输出流 ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(fileName)));