第12章输入输出流、文件及数据库操作
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第十二章输入输出流、文件及数据库
任何一个程序都有一个目的,即输入(提供)什么数据(信息)可输出(获得)所期望的结果。到目前为止,我们在程序中所讨论的输入和输出操作都是在标准设备文件上进行的。本章将简要介绍对数据流、数据文件和数据库文件的输入和输出操作。
12.1 输入输出流
输入输出是程序设计的重要组成部分,任何程序设计语言都提供对输入输出的支持。Java也不例外,它采用数据流的形式传送数据。
12.1.1 流的概念
所谓流(Stream),简单地说,即是计算机中数据的流动。
程序运行需要取得数据,这些数据可以通过用户从键盘输入获得,也可以从磁盘文件调入,还可以接收来自网络上的数据信息,程序在获得数据之后对其进行处理,并将处理结果输出到屏幕、磁盘文件或打印机上,也可输送到网络上(如远程打印机、网络用户等)。
对程序而言,数据信息从某个地方流向程序中,这就是输入流;数据信息从程序中发送到某个目的地,这就是输出流。
无论是输入流还是输出流,Java提供了如下两种方式进行处理:
1)字节(byte)方式
以字节方式处理的是二进制数据流(简称为字节流)。
用二进制的格式可以表示许多类型的数据,比如数字数据、可执行程序代码、因特网通信和类文件代码等等。
2)字符(character)方式
以字符方式处理的数据流称为字符流。它不同于字节流,因为Java使用Unicode字符集,存放一个字符需要两个字节。因此这是一种特殊类型的字节流,它只处理文本化的数据。所有涉及文本数据处理,诸如文本文件、网页以及其它常见的文本类型都应该使用字符流。
下边我们将分别介绍字节流和字符流的功能及应用。
12.1.2 字节流
在输入和输出流中用到了许多类,它们形成了一种非常合理的结构,只要我们了解了它们之间的相互关系,就可以正确地使用了。
1
下边我们先介绍字节输入流类的功能及应用。
1. 字节输入流类(InputStream)
InputStream类是一个抽象类,它是字节输入流的顶层类。我们不能直接创建InputStream 对象,要进行字节输入流的操作,还要靠创建它的子类对象实现。InputStream类被放在java.io 包中,它的派生结构如下:
class java.io.InputStream
|-class java.io.ByteArrayInputStream
|-class java.io.FileInputStream
|-class java.io.FilterInputStream
|-class java.io.BufferedInputStream
|-class java.io.DataInputStream
|-class java.io.LineNumberInputStream
|-class java.io.PushbackInputStream
|-class java.io.ObjectInputStream
|-class java.io.PipedInputStream
|-class java.io.SequenceInputStream
|-class java.io.StringBufferInputStream
InputStream类中提供了一系列的方法用来完成从字节输入流读取数据的操作,下边简要介绍一些常用的方法及其应用。
1)InputStream类的常用方法
abstract int read() 从输入流中读取一个字节并返回整数值(0~255)。如果流中无字节可读,则返回-1。该方法是一个抽象方法,在其子类中实现它。
int read(byte[] b) 从输入流中读取字节放入字节数组b中并返回实际读取的字节数。
int read(byte[] b, int off, int len) 从流中读取len个字节存入字节数组b从off开始的位置中,并返回实际读取的字节数。
long skip(long n) 从流中当前的位置跳过n个字节。
int available() 返回可以从流中读取的字节数。
void close() 关闭输入流。
void mark(int readlimit) 在流中当前位置处做一个标记。以便其后使用reset()方法返回该点。如果在做了标记之后又从流中读取了超过readlimit个字节,则标记无效。
void reset() 将读取位置返回到标记的位置。如果之前没做标记或该流不支持标记将抛出异常。
boolean markSupported() 测试该流是否支持标记。
注意:读取字节流的方法都引入了异常处理,如果遇到读错误,将抛出一个IOException 异常;如果遇到对象为null,则抛出NullPointerException异常;如果使用数组超出范围,则抛出IndexOutOfBoundsException异常。
2)使用字节输入流
如前所述,使用字节输入流的操作需要创建ImputStream子类的对象来实现。下边我们先介绍一下DataInputStream子类,然后再举一个例子,说明一下字节输入流的操作。
2
(1)DataInputStream构造方法
DataInputStream(InputStream in) 用基本的InputStream对象in创建对象。
(2)DataInputStream常用方法
除了继承父类的所有方法之外,还实现了DataInput接口中所有的方法,这些方法主要是读取各类数据,除了读取八种(boolean,byte,char,short,int,float,long, double) 基本类型数据的方法外,还有如下方法:
int readUnsignedByte() 以无符号字节数的方式读取流中的数据。
int readUnsignedShort() 以无符号短整数的方式读取流中的数据。
String readUTF() 以UTF-8数据格式读取流中的数据。
static String readUTF(DataInput in) 以UTF-8数据格式读取由in指定流中的数据。
int skipBytes(int n) 跳读n个字节。
(3)应用举例
例12.1 从键盘上输入5个字节数据放入字节数组中并显示出来。
/* 程序名ByteInputStreamApp.java*/
import java.io.*;
public class ByteInputStreamApp
{
public static void main(String [] args)
{
byte byteArray[]=new byte[5]; //定义字节数组
DataInputStream data=new DataInputStream(System.in);//创建对象
try //捕获I/O错误
{
System.out.print("从键盘上输入5个字节数据:");
data.read(byteArray); //从键盘上输入字节数据放入数组中
}
catch(IOException e)
{
System.out.println(e.toString()); //输出出错信息
}
System.out.print("从流中获取的5个字节数据: ");
for(int i=0;i<5;i++) System.out.print(byteArray[i]+" ");
System.out.println("");
}
}
在程序中,我们使用System.in创建数据输入流对象,如前所述System.in既是System 类的一个属性成员也是一个InputStream对象。
另外,我们使用了try~catch捕获异常机制的语句,主要是捕获data.read (byteArray)语句执行过程中可能发生的I/O错误,这是系统要求的,对于所有涉及流输入和输出的语句都必须对可能出现的错误进行捕获的处理,如果没有捕获错误的处理,系统在编译时将给出错误
3