第5章数据存储
本章中,我们将了解如何进行读取和存储数据、数据存储的不同形式及其所涉及的相关知识,由此我们便能够分辨出它们的优缺点。
5.1本 章 任 务
理论任务: 了解I/O的基本概念,对于文件系统有基本认识,学会使用JDBC连接数据库,并对数据库中的数据进行存储和读取,同时学习MVC设计模式,将编写的程序代码按照MVC设计模式进行重构。
实践任务: 在之前的章节中,booklist中的内容都是存储在内存中的,不能保证数据的长期存储。在这一章中,我们将会把数据存储在硬盘中,通过文件或者数据库的形式对数据进行长期保存,保证数据不丢失。同时,我们将讲解MVC的设计模式,并对之前的代码进行重构,将显示内容、数据操作类、控制类进行分类和归类,降低程序耦合度,以便提高开发效率、方便代码维护。
5.2IO
IO(输入输出)在Java及众多编程语言中都是极其重要的一部分,在Java中,输入输出主要采用数据流的方式实现,在本节中,我们将讲解基本的输入输出方法。
5.2.1基本IO
正如2.7节中提到的,按照标准的I/O模型,Java提供了System.in、System.out进行输入输出操作,在使用过程中,因为System.out被包装,我们可以直接使用,但是System.in是一个没有被包装过的InputStream,所以在使用过程中,我们需要自己包装System.in。并且在其使用过程中,通常我们使用readline()一次一行读取数据,但是在实际操作中,除了对数据进行一行一行的读取,我们还可能对数据进行数组的存储或者字符的截取。这时,我们会发现,针对不知道长度或者大小的输入,我们的操作会变得困难而复杂,所以在下节中,我们将会讲解更方便的IO操作。
5.2.2更好用的IO
Java的输入输出功能都是基于类库java.io包来实现,java.io库提供了全面的IO接口,并且Java中IO是以流为基础的。流是什么呢?流是一组有顺序的,有起点和终点的字节集合,当程序需要读取数据的时候,就会开启一个通向数据源的流,Java将来自不同源和目标的数据统一抽象为数据流。
在Java的IO操作中,对流的操作分为读和写两种。根据流的运动方向,我们将流分为输入流和输出流,这里的输入输出都是以计算机内存为参照物的,所以,从键盘等外设流入计算机内存的数据序列称为输入流,反之,从计算机内存流出的数据序列称为输出流。
Java按照流中元素的基本类型,将数据流分为字节流和字符流。以字节为单位传输数据的流称为字节流; 以字符为单位传输数据的流称为字符流。根据功能的不同,又将流分为节点流和处理流。直接从数据源读写数据的流为节点流; 从其他的流上进行数据处理的流为处理流。Java中所有的流类型分别继承四种抽象流类,如表51所示。
表51四种抽象输入输出流
字节流
字符流
输入流
InputStream
Reader
输出流
OutputStream
Write 在本节中我们将根据流的分类从输入和输出方面讲解更好用的IO。
1. 输入流
在Java中,把能够读取一个字节序列的对象称为字节输入流,把能够写一个字节的对象称为字节输出流。
输入流又分为字节输入流和字符输入流,这两个类下又分为多个类,其中,字节输入流依靠InputStream类及其子类实现,字符输入流由Reader类及其子类实现。
(1) InputStream类
InputStream类是一个抽象类,是所有基于字节的输入流的超类,InputStream类的定义如下。
public abstract class InputStream implements Closeable; 可以看出,InputStream抽象类继承了Closeable类,由于InputStream作为一个抽象类,不能用new创造实例,所以对字节输入流的操作,都是由它的子类对象完成,它的子类结构如图51所示。 图51InputStream类的派生类
从图51中,我们可以看到,字节输入流根据类型和操作方式不同,划分了不同的子类,其中我们主要讲解文件字节输入流(FileInputStream)。
FileInputStream可以从文件系统中的某个文件中获得输入字节,简单地说,就是用于读取本地文件中的字节数据,FileInputStream类的构造函数主要有以下三种。
FileInputStream(File flie): 以file指定的文件对象创建文件输入流。
FileInputStream(FileDescriptor fdObj): 以fdObj指定的文件描述对象创建文件输入流。
FileInputStream(String name): 以字符串name指定的文件名创建文件输入流。
可以看到,三个构造函数的区别只是参数的不同,所以FileInputStream构造方法可以接受字符串、file对象。其次,它的构造函数在使用的时候需要指定文件的来源,FileInputStream类的常用方法如表52所示。
表52FileInputStream类的常用方法