第12章输入输出流文件及数据库操作.docx
- 文档编号:23560494
- 上传时间:2023-05-18
- 格式:DOCX
- 页数:70
- 大小:373.11KB
第12章输入输出流文件及数据库操作.docx
《第12章输入输出流文件及数据库操作.docx》由会员分享,可在线阅读,更多相关《第12章输入输出流文件及数据库操作.docx(70页珍藏版)》请在冰豆网上搜索。
第12章输入输出流文件及数据库操作
第十二章输入输出流、文件及数据库
任何一个程序都有一个目的,即输入(提供)什么数据(信息)可输出(获得)所期望的结果。
到目前为止,我们在程序中所讨论的输入和输出操作都是在标准设备文件上进行的。
本章将简要介绍对数据流、数据文件和数据库文件的输入和输出操作。
12.1输入输出流
输入输出是程序设计的重要组成部分,任何程序设计语言都提供对输入输出的支持。
Java也不例外,它采用数据流的形式传送数据。
12.1.1流的概念
所谓流(Stream),简单地说,即是计算机中数据的流动。
程序运行需要取得数据,这些数据可以通过用户从键盘输入获得,也可以从磁盘文件调入,还可以接收来自网络上的数据信息,程序在获得数据之后对其进行处理,并将处理结果输出到屏幕、磁盘文件或打印机上,也可输送到网络上(如远程打印机、网络用户等)。
对程序而言,数据信息从某个地方流向程序中,这就是输入流;数据信息从程序中发送到某个目的地,这就是输出流。
无论是输入流还是输出流,Java提供了如下两种方式进行处理:
1)字节(byte)方式
以字节方式处理的是二进制数据流(简称为字节流)。
用二进制的格式可以表示许多类型的数据,比如数字数据、可执行程序代码、因特网通信和类文件代码等等。
2)字符(character)方式
以字符方式处理的数据流称为字符流。
它不同于字节流,因为Java使用Unicode字符集,存放一个字符需要两个字节。
因此这是一种特殊类型的字节流,它只处理文本化的数据。
所有涉及文本数据处理,诸如文本文件、网页以及其它常见的文本类型都应该使用字符流。
下边我们将分别介绍字节流和字符流的功能及应用。
12.1.2字节流
在输入和输出流中用到了许多类,它们形成了一种非常合理的结构,只要我们了解了它们之间的相互关系,就可以正确地使用了。
下边我们先介绍字节输入流类的功能及应用。
1.字节输入流类(InputStream)
InputStream类是一个抽象类,它是字节输入流的顶层类。
我们不能直接创建InputStream对象,要进行字节输入流的操作,还要靠创建它的子类对象实现。
InputStream类被放在java.io包中,它的派生结构如下:
classjava.io.InputStream
|-classjava.io.ByteArrayInputStream
|-classjava.io.FileInputStream
|-classjava.io.FilterInputStream
|-classjava.io.BufferedInputStream
|-classjava.io.DataInputStream
|-classjava.io.LineNumberInputStream
|-classjava.io.PushbackInputStream
|-classjava.io.ObjectInputStream
|-classjava.io.PipedInputStream
|-classjava.io.SequenceInputStream
|-classjava.io.StringBufferInputStream
InputStream类中提供了一系列的方法用来完成从字节输入流读取数据的操作,下边简要介绍一些常用的方法及其应用。
1)InputStream类的常用方法
abstractintread()从输入流中读取一个字节并返回整数值(0~255)。
如果流中无字节可读,则返回-1。
该方法是一个抽象方法,在其子类中实现它。
intread(byte[] b)从输入流中读取字节放入字节数组b中并返回实际读取的字节数。
intread(byte[] b,intoff,int len)从流中读取len个字节存入字节数组b从off开始的位置中,并返回实际读取的字节数。
longskip(long n)从流中当前的位置跳过n个字节。
intavailable()返回可以从流中读取的字节数。
voidclose()关闭输入流。
voidmark(int readlimit)在流中当前位置处做一个标记。
以便其后使用reset()方法返回该点。
如果在做了标记之后又从流中读取了超过readlimit个字节,则标记无效。
voidreset()将读取位置返回到标记的位置。
如果之前没做标记或该流不支持标记将抛出异常。
booleanmarkSupported()测试该流是否支持标记。
注意:
读取字节流的方法都引入了异常处理,如果遇到读错误,将抛出一个IOException异常;如果遇到对象为null,则抛出NullPointerException异常;如果使用数组超出范围,则抛出IndexOutOfBoundsException异常。
2)使用字节输入流
如前所述,使用字节输入流的操作需要创建ImputStream子类的对象来实现。
下边我们先介绍一下DataInputStream子类,然后再举一个例子,说明一下字节输入流的操作。
(1)DataInputStream构造方法
DataInputStream(InputStream in)用基本的InputStream对象in创建对象。
(2)DataInputStream常用方法
除了继承父类的所有方法之外,还实现了DataInput接口中所有的方法,这些方法主要是读取各类数据,除了读取八种(boolean,byte,char,short,int,float,long,double)基本类型数据的方法外,还有如下方法:
intreadUnsignedByte()以无符号字节数的方式读取流中的数据。
intreadUnsignedShort()以无符号短整数的方式读取流中的数据。
StringreadUTF()以UTF-8数据格式读取流中的数据。
static StringreadUTF(DataInput in)以UTF-8数据格式读取由in指定流中的数据。
intskipBytes(int n)跳读n个字节。
(3)应用举例
例12.1从键盘上输入5个字节数据放入字节数组中并显示出来。
/*程序名ByteInputStreamApp.java*/
importjava.io.*;
publicclassByteInputStreamApp
{
publicstaticvoidmain(String[]args)
{
bytebyteArray[]=newbyte[5];//定义字节数组
DataInputStreamdata=newDataInputStream(System.in);//创建对象
try//捕获I/O错误
{
System.out.print("从键盘上输入5个字节数据:
");
data.read(byteArray);//从键盘上输入字节数据放入数组中
}
catch(IOExceptione)
{
System.out.println(e.toString());//输出出错信息
}
System.out.print("从流中获取的5个字节数据:
");
for(inti=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错误,这是系统要求的,对于所有涉及流输入和输出的语句都必须对可能出现的错误进行捕获的处理,如果没有捕获错误的处理,系统在编译时将给出错误提示,程序编译未能获得通过。
编译、运行上边的程序,结果如图12.1所示。
程序运行时,我们从键盘上输入5个字符,它们被放入字节数组中,输出它们的值,它们以ascii码值的形式展现在我们面前。
图12.1例12.1运行结果
2.字节输出流(OutputStream)
与InputStream类似,OutputStream是字节输出流的顶层类,它也是一个抽象类。
OutputStream类的派生结构如下:
|-classjava.io.OutputStream
|-classjava.io.ByteArrayOutputStream
|-classjava.io.FileOutputStream
|-classjava.io.FilterOutputStream
|-classjava.io.BufferedOutputStream
|-classjava.io.DataOutputStream
|-classjava.io.PrintStream
|-classjava.io.ObjectOutputStream
|-classjava.io.PipedOutputStream
OutputStream类中定义了用来完成从输出流输出数据的—系列方法。
下边简要介绍一些常用的方法及其应用。
1)OutputStream类常用方法
abstractvoidwrite(int b)将b的低位字节写入到输出流。
这是一个抽象方法,需要在其子类中实现它。
voidwrite(byte[] b)把字节数组b写入输出流。
voidwrite(byte[] b,int off,int len)把字节数组b中从off位置开始的len个字节写入输出流。
voidflush()立即将流缓冲区中的数据输出。
正常情况下,写入数据到输出流时,write()方法并不能将数据直接写到与输出流相连的设备上,而是先存放在流缓冲区中,等到缓冲区中的数据积累到一定数量时才写到设备上。
这样处理可以降低计算机对设备的读写次数,提高系统的效率。
但是某些情况下,缓冲区中的数据不满时就需要将它写到设备上,诸如数据的写入已经完成、关闭输出流之前等,均应执行flush()方法。
voidclose()关闭输出流。
该方法先执行flush()方法把缓冲区中的数据写到流设备上,然后再关闭输出流。
注意:
与InputStream类似,写入字节流的方法也都引入了异常处理,如果遇到写错误,将抛出一个IOException异常。
2)使用字节输出流
与使用字节输入流类似,使用字节输出流的操作也需要创建OutputStream子类的对象来实现。
下边先介绍一下DataOutputStream子类,然后再举一个例子,说明一下字节输出流的操作。
(1)DataOutputStream构造方法
DataOutputStream(OutputStream out)以OutputStream对象out为参数创建对象。
(2)DataOutputStream常用方法
除了继承父类的所有方法之外,还实现了DataOutput接口中所有的方法,这些方法主要是写入各类数据,除了写入八种(boolean,byte,char,short,int,float,long,double)基本类型数据的方法(writedataType(dataTypev))外,还提供了如下常用方法:
intsize()返回迄今为止写入流中的字节计数。
voidwriteChars(String s)将字符串s写入到输出流中。
voidwriteUTF(String str) 将字符串str以UTF-8格式写入到输出流中。
(3)应用举例
例12.2修改例12.1,从键盘上输入5个字节数据放入字节数组中并将它写入基本的输出流中。
/*程序名ByteOutputStreamApp.java*/
importjava.io.*;
publicclassByteOutputStreamApp
{
publicstaticvoidmain(String[]args)
{
bytebyteArray[]=newbyte[5];//定义字节数组
DataInputStreamdata=newDataInputStream(System.in);//创建对象
DataOutputStreamout=newDataOutputStream(System.out);
try//捕获I/O错误
{
System.out.print("从键盘上输入5个字节数据:
");
data.read(byteArray);//从键盘上输入字节数据放入数组中
System.out.print("将字节数组写出的结果:
");
out.write(byteArray);//将字节数组写出
}
catch(IOExceptione)
{
System.out.println(e.toString());//输出出错信息
}
System.out.println("");
}
}
请读者运行该程序,比较一下它和例12.1的区别之处,进一步加深对字节流的理解。
3.综合应用举例
字节流中用的最多的是读写文件数据的文件流(FileInputStream和FileOutputStream)和如上所述的读写基本数据的数据流(DataInputStream和DataOutputStream)。
下边我们先简要介绍一下FileInputStream和FileOutputStream类,然后再举两个应用的例子。
1)FileInputStream类
FileInputStream类构造方法如下:
FileInputStream(File file) 以file指定的文件对象创建文件输入流。
FileInputStream(FileDescriptor fdObj)以fdObj指定的文件描述符对象创建文件输入流。
FileInputStream(String name) 以字符串name指定的文件名创建文件输入流。
FileInputStream除了继承父类的方法之外,还提供了如下常用方法:
FileChannelgetChannel() 获得与文件输入流相连接的唯一的FileChannel对象。
FileDescriptorgetFD() 获得与文件输入流相连接的文件描述符对象。
2)FileOutputStream类
FileOutputStream类构造方法如下:
FileOutputStream(File file) 以file指定的文件对象创建文件输出流。
FileOutputStream(File file,boolean append)以file指定的文件对象创建文件输出流。
如果append为true,则数据被添加到文件的尾部而不是开头。
FileOutputStream(FileDescriptor fdObj) 以fdObj指定的文件描述符对象创建文件输出流。
FileOutputStream(String name)以字符串name指定的文件名创建文件输出流。
FileOutputStream(String name,boolean append) 以字符串name指定的文件名创建文件输出流。
append的作用如上所述。
FileOutputStream 类除了继承父类的方法之外,还提供了如下常用方法:
FileChannelgetChannel() 获得唯一的与该文件输出流相连接的FileChannel对象。
FileDescriptorgetFD() 获得与该输出流相连接的文件描述符对象。
.
3)应用示例
例12.3使用字节流建立文件并输出文件内容。
/**程序名File_Read_Write.java
*本示例主要演示数据输入/输出流与文件输入/输出流的简单应用
*/
importjava.io.*;
publicclassFile_Read_Write
{
publicstaticvoidmain(String[]arguments)
{
byte[]data=newbyte[50];
try
{
DataInputStreamin=newDataInputStream(System.in);//创建数据输入流对象;
FileOutputStreamfile=newFileOutputStream("data1.dat");//创建文件输出流
System.out.println("输入不多于50个字符:
");
in.read(data);//将键盘上输入的字符读入字节数组
file.write(data);//将字节数组的元素值写入流
file.close();//关闭文件输出流
in.close();//关闭数据输入流
FileInputStreamfile1=newFileInputStream("data1.dat");//创建文件输入流
DataOutputStreamout=newDataOutputStream(System.out);//创建数据输出流
intn=file1.read(data);//从文件输入流中读取数据放入字节数组中
System.out.println("从文件中读取的"+n+"字节的数据如下:
");
out.write(data);
file1.close();//关闭文件输入流
out.close();//关闭数据输出流
}
catch(IOExceptione){System.out.println("Error-"+e.toString());}
}
}
例12.4使用文件输入/输出流复制文件。
/*程序名FileCopy.java*/
importjava.io.*;
publicclassFileCopy
{
publicstaticvoidmain(String[]arguments)
{
byte[]data=newbyte[50];
intn=0;
try
{//创建文件输入流对象
FileInputStreamfile1=newFileInputStream("File_Read_Write.class");
//创建文件输出流对象
FileOutputStreamfile2=newFileOutputStream("File_Read_Write2.class");
while((n=file1.available())>0)//当文件中还有字节可读时
{
file1.read(data);//将文件的内容读入字节数组
if(n>=50){file2.write(data);}//若文件没有读完,将读取的整个数组内容写入
else{file2.write(data,0,n);}//将最后的n个字节写入
}
file2.close();//关闭文件输出流
file1.close();//关闭文件输入流
}
catch(IOExceptione){System.out.println("Error-"+e.toString());}
System.out.println("File_Read_Write.class复制到File_Read_Write2.class完成!
");
}
}
12.1.3字符流
下边简要介绍字符输入流和字符输出流的功能和应用。
1.字符输入流(Reader类)
Reader类是一个抽象类,是字符输入流的顶层类。
Reader类的派生结构如下:
|-classjava.io.Reader
|-classjava.io.BufferedReader
|-classjava.io.LineNumberReader
|-classjava.io.CharArrayReader
|-classjava.io.FilterReader
|-classjava.io.PushbackReader
|-classjava.io.InputStreamReader
|-classjava.io.FileReader
|-classjava.io.PipedReader
|-classjava.io.StringReader
尽管不能直接创建Reader对象进行流的操作,但Reader类提供了读取字符流的常用方法。
下边我们介绍Reader类的功能和使用其子类对象操作字符流的应用。
1)Reader类的方法
Reader类定义了如下常用的方法:
intread()从流中读取一个字符并将它作为一个int值返回。
如果读到流的结束位置,将返回-1。
intread(char[] cbuf)将从流中读取字符放入字符数组cbuf中,并返回读取的字符数。
abstractintread(char[] cbuf,int off,int len)从流中读取len个字符放入cbuf数组中从off位置开始的元素中。
这是一个抽象方法,在其子类中实现它。
longskip(long n)跳过流中n个字符并返回跳过的字符数。
如果流中字符个数小于n,则返回值小于n。
.
booleanready()测试该流是否已准备好可以读取。
如果已准备好,返回true;否则返回false。
booleanmarkSupported()测试该流是否可标记的。
如果是可标记的,返回true;否则返回false。
voidmark(int readAheadLimit)在流中标记当前位置,readAheadLimit指定在不丢失当前标记位置记录的情况下允许读取的最大字符数。
voidreset()将流的读取位置定位到前一个标记位置,如果没有标记,则定位到流的开始位置。
abstractvoidclose()关闭字符输入流。
这是一个抽象方法,在其子类中实现它。
2)使用字符输入流
如前所述,必须创建Reader类的子类对象来操作字符流。
一般我们常使用字符输入流来处理文本文件,FileReader类用于从一个文件中读取字符流。
如果想一次在流中读取一行字符时,BufferReader类具有更高的效率。
下边先简单介绍一下常用子类的功能,然后再加以应用。
(1)BufferReader类
BufferReader类构造方法如下:
BufferedReader(Reader in)创建一个系统默认大小的缓冲字符流。
BufferedReader(Reader in,int size) 创建一个由size指定大小的缓冲字符流。
除了继承父类的方法之外,BufferReader还提供了如下常用方法:
StringreadLine() 读取一行文本。
如果已无字符可读即已到流的结尾,将返回null。
一般
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 12 输入输出 文件 数据库 操作