




已阅读5页,还剩86页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章输入输出流,本章知识框图,学习重点:,掌握基本输入输出流。掌握按数据类型操作输入输出流。掌握输入输出对象。掌握文件/目录操作。,Java采用“流”(Stream)来完数据的输入(Input)和输出(Output),输入输出简称I/O。从外部数据源将数据读入程序的流称为输入流,从程序中将数据写入外部数据源的流称为输出流。外部数据源可以是磁盘文件、程序、内存或硬件设备。可以按字节、字符或类型化的数据进行输入输出。也可以将对象写入文件,或从文件中读出对象。本章将详细介绍各种常用的输入输出流操作。,9.1基本输入输出流,基本的输入输出流包括字节流、字符流和缓冲流。在输入时,可使用Scanner对象从流读取特定类型的数据。在输出时,可以对输出格式进行控制。,9.1.1字节流,字节流按字节(8位二进制)输入和输出数据。Java定义了很多字节流类,这些类都是两个抽象类InputStream和OutputStream.的派生类。本节主要讲解两个基本的字节流类:FileInputStream(文件输入流)和FileOutputStream(文件输出流)。,1、创建FileInputStream对象,可用下列方法创建文件输入流对象:(1)FileInputStream(Filefile)用File对象创建一个FileInputStream对象,File对象指定实际访问的磁盘文件。例如:FileInputStreamdatain=newFileInputStream(newFile(datafile.txt);文件datafile.txt没有指定路径,默认与应用程序在相同目录中。如果未找到指定文件,则抛出FileNotFoundException异常。(2)FileInputStream(FileDescriptorfdObj)用FileDescriptor对象创建一个FileInputStream对象。例如:FileInputStreamdatain=newFileInputStream(FileDescriptor.in);FileDescriptor定义了3个静态对象,FileDescriptor.in等价于System.in,FileDescriptor.out等价于System.out,FileDescriptor.err等价于System.err。创建FileInputStream对象时,只能使用FileDescriptor.in。采用这种方式创建的FileInputStream对象可以从键盘读取数据。(3)FileInputStream(Stringname)用指定的文件名创建一个FileInputStream对象。例如:FileInputStreamdatain=newFileInputStream(datafile.txt);Windows环境中的路径分隔符号为“”,可用“”或“/”作为路径分隔符。例如:FileInputStreamdatain=newFileInputStream(d:javatempchapter09datafile.txt);,2、FileInputStream对象操作,FileInputStream对象常用操作如下:available():返回可读的字节数。若没有可读数据,返回值为0。close():关闭文件输入流。read():从输入流读取一个字节,返回值类型为int。若没有可读数据,返回-1。read(byteb):从输入流读取数据,按顺序放入b的各个数组元素中。返方法回值类型为int,表示从流中读取的总的字节数。若没有可读数据,返回值为-1。read(byteb,intbindex,intcount):最多从输入流读取count个字节,按顺序放入b数组中下标从bindex开始的元素中。返方法回值类型为int,表示从流中读取的总的字节数。若没有可读数据,返回值为-1。skip(longn):在流中跳过n个字节。n不能为负数,否则产生错误。FileInputStream对象的各个方法在出现错误时,会抛出IOException异常。IOException异常属于检查异常,必须在代码中捕捉或声明方法抛出,【例9.1】,使用FileInputStream对象读取文件数据。(源文件位置:光盘:chapter09.useFileInputStream.java,光盘:chapter09datafile.txt)useFileInputStream从文本文件datafile.txt中读取数据,并显示在命令提示符窗口中。datafile.txt文件内容如下:1:firstline2:secondline3:thirdline,程序代码如下:importjava.io.*;publicclassuseFileInputStreampublicstaticvoidmain(Stringargs)throwsIOExceptionFileInputStreamin=null;tryin=newFileInputStream(datafile.txt);System.out.println(文件总字节数:+in.available();System.out.println(*文件内容如下*);intc;,while(in.available()!=0)/如果还有可读数据则循环c=in.read();/读一个字节/read方法返回的是int型数据,要按字符输出,/所以用char强制转换数据类型。/如果不转换,输出为字符ASCII码的十进制值System.out.print(char)c);/输出System.out.println(*文件内容结束*);in.close();/关闭流in=newFileInputStream(datafile.txt);/重新建立文件输入流intcount=0;byteb=newbyte5;in.skip(16);/跳过16个字节,if(in.available()!=0)count=in.read(b);/从流读取数据到字节数组System.out.print(用数组读出的数据:);for(inti=0;icount;i+)System.out.printf(%-4d,bi);System.out.print(n对应的字符:);for(inti=0;icount;i+)System.out.printf(%-4s,(char)bi);finallyif(in!=null)in.close();/关闭流,代码中使用了FileInputStream的各种方法,这些方法可能产生IOException异常。代码中没有使用catch处理IOException异常,所以在main方法的参数表之后使用throws关键字声明方法可能抛出IOException异常。程序在finally代码块中关闭文件输入流。如果没有在程序中调用close方法关闭流,系统可自动将其关闭。close方法在关闭流的同时,释放维护流使用的相同资源,所以建议读者在代码中显式调用close方法关闭流,以便提供相同效率。程序将关闭流操作放在finally代码块中,这是因为不管程序运行是否有错,finally代码都会执行,从而保证关闭流。说明:本例中datafile.txt文件内容为ASCII码字符。如果文件中包含非ASCII码字符,比如汉字,按字节读取会导致非ASCII码字符不能读取和显示。,3、创建FileOutputStream对象,可用下列方法创建FileOutputStream对象:(1)FileOutputStream(Filefile)用指定File对象创建文件输出流,向File对象指定的文件输出数据。该方法始终创建一个新文件。如果已存在同名文件,原文件被覆盖。File对象指定的是一个文件夹或者文件路径错误,则会产生FileNotFoundException异常。例如:FileOutputStreamdataout=newFileOutputStream(newFile(outdatafile.txt);(2)FileOutputStream(Filefile,booleanappend)参数append为false时,与FileOutputStream(Filefile)相同。参数append为true时,表示向文件添加数据。例如:FileOutputStreamdataout=newFileOutputStream(newFile(outdatafile.txt),true);(3)FileOutputStream(FileDescriptorfdObj)用FileDescriptor对象创建文件输出流。例如:FileOutputStreamdataout=newFileOutputStream(FileDescriptor.out);(4)FileOutputStream(Stringname)用指定文件名创建文件输出流,向文件输出数据,与FileOutputStream(Filefile)方法类似。例如:FileOutputStreamdataout=newFileOutputStream(outdatafile.txt);(5)FileOutputStream(Stringname,booleanappend)参数append为false时,与FileOutputStream(Stringname)相同。参数append为true时,表示向文件添加数据。例如:FileOutputStreamdataout=newFileOutputStream(outdatafile.txt,true);,4、FileOutputStream对象操作,FileOutputStream对象常用操作如下:close():关闭文件输出流。flush():刷新流,即向流中的数据全部写入文件。write(intn):向文件写入一个字节。如果n大于255,即多余一个字节,则将n的最后一个字节写入文件。写入文件的字节视为字符的ASCII码。例如,write(65)写入文件的是字符A(其ASCII码为65)。write(byteb):将字节数组b中的数据按顺序写入文件。write(byteb,intbindex,intcount):将字节数组b中下标从bindex开始的count个元素写入文件。FileOutputStream对象的各个方法在出现错误时,会抛出IOException异常。,【例9.2】,使用FileOutputStream对象向文件写数据。(源文件位置:光盘:chapter09.useFileOutputStream.java,光盘:chapter09outdatafile.txt,光盘:chapter09datafile2.txt)useFileOutputStream首先将文本文件datafile2.txt中的数据复制到新文件outdatafile.txt中,再为文件添加部分数据。datafile2.txt文件内容如下:春晓春眠不觉晓处处闻啼鸟夜来风雨声花落知多少,程序代码如下:/将文件datafile2.txt中的数据复制到outdatafile.txt文件中,并添加部分数据importjava.io.*;publicclassuseFileOutputStreampublicstaticvoidmain(Stringargs)throwsIOExceptionFileInputStreamin=null;FileOutputStreamout=null;tryin=newFileInputStream(datafile2.txt);out=newFileOutputStream(outdatafile.txt);,/复制文件while(in.available()!=0)/如果还有可读数据则循环out.write(in.read();out.close();/关闭输出流/重新打开文件,添加数据out=newFileOutputStream(outdatafile.txt,true);out.write(n);/写入一个换行符/24897的二进制为110000101000001,第二个字节为字符A的/ASCII码,所以下面的语句实际写入的是字符Aout.write(24897);out.write(n);/写入一个换行符byteb=newbyte10;for(bytei=0;ib.length;i+)bi=(byte)(97+i);out.write(b);/将输入写入文件,实际写入abcdefghijSystem.out.println(文件操作结束!);finallyif(in!=null)in.close();/关闭流if(out!=null)out.close();/关闭流,9.1.2字符流,字符流按字符读取和写入数据。Java采用Unicode字符,在读写文件时,字符流可以自动将文件中的本地字符转换为Unicode字符。本节介绍两个字符流类:FileReader(读文件)和FileWriter(写文件)。FileReader和FileWriter类的基类分别为InputStreamReader和OutputStreamWriter类,InputStreamReader和OutputStreamWriter类分别继承抽象类Reader和Writer。InputStreamReader和OutputStreamWriter类可以按本地字符集和指定字符集读写文件。文件中的数据仍按字节读写,InputStreamReader和OutputStreamWriter流完成字符和字节的转换。FileReader和FileWriter流采用本地字符集读写文件。,1、创建FileReader对象,可用下列方法创建FileReader对象:FileReader(Filefile)用File对象创建一个FileReader对象,File对象指定实际访问的磁盘文件。例如:FileReaderdatain=newFileReader(newFile(datafile.txt);FileReader(FileDescriptorfdObj)用FileDescriptor对象创建一个FileReader对象。例如:FileReaderdatain=newFileReader(FileDescriptor.in);FileReader(Stringname)用指定的文件名创建一个FileReader对象。例如:FileReaderdatain=newFileReader(d:javatempchapter09datafile.txt);,2、FileReader流常用操作,FileReader流常用操作如下:getEncoding():返回文件采用的字符集。close():关闭流。read():从流读取一个字符,返回值类型为int。若没有可读数据,返回-1。read(charb):从流读取字符,按顺序放入b的各个数组元素中。返方法回值类型为int,表示从流中读取的总的字符数。若没有可读数据,返回值为-1。read(charb,intbindex,intcount):最多从输入流读取count个字符,按顺序放入b数组中下标从bindex开始的元素中。返方法回值类型为int,表示从流中读取的总的字符数。若没有可读数据,返回值为-1。skip(longn):在流中跳过n个字符。n不能为负数,否则产生错误。,3、创建FileWriter对象,可用下列方法创建FileWriter对象:FileWriter(Filefile)用指定File对象创建FileWriter流,向File对象指定的文件输出数据。该方法始终创建一个新文件。如果已存在同名文件,原文件被覆盖。File对象指定的是一个文件夹或者文件路径错误,则会产生FileNotFoundException异常。例如:FileWriterdataout=newFileWriter(newFile(outdatafile.txt);FileWriter(Filefile,booleanappend)参数append为false时,与FileWriter(Filefile)相同。参数append为true时,表示向文件添加数据。例如:FileWriterdataout=newFileWriter(newFile(outdatafile.txt),true);,FileWriter(FileDescriptorfdObj)用FileDescriptor对象创建FileWriter流。例如:FileWriterdataout=newFileWriter(FileDescriptor.out);FileWriter(Stringname)用指定文件名创建FileWriter流,向文件输出数据,与FileWriter(Filefile)方法类似。例如:FileWriterdataout=newFileWriter(outdatafile.txt);FileWriter(Stringname,booleanappend)参数append为false时,与FileWriter(Stringname)相同。参数append为true时,表示向文件添加数据。例如:FileWriterdataout=newFileWriter(outdatafile.txt,true);,4、FileWriter对象操作,FileWriter对象常用操作如下:close():关闭FileWriter流。flush():刷新流,即向流中的数据全部写入文件。getEncoding():返回文件采用的字符集。write(intn):向文件写入一个字符,n为字符的Unicode码。write(charb):将字符数组b写入文件。write(charb,intbindex,intcount):将字符数组b中下标从bindex开始的count个元素写入文件。write(Stringb):将字符串b写入文件。write(Stringb,intindex,intcount):将字符串b中序号从index开始的count个字符写入文件。append(charc):将字符c写入文件。append(CharSequenceb):将字符序列b写入文件。String类型为一个典型的实现了CharSequence接口的类。append(CharSequenceb,intstart,intend):将字符串序列b中下标start开始到end的字符写入文件。,9.1.3缓冲流,前面前面介绍的字节流和字符流均未使用内存缓冲区,也就是说,每次读写一个字节或字符都是直接访问文件,这会导致大量数据读写时频繁访问文件。缓冲输入输出流则是在内存中创建一个缓冲区来缓存数据。程序只是从缓冲区读取数据,不直接访问文件。输入数据时,缓冲流在缓冲区为空时自动从文件读取数据填满缓冲区。输出数据时,数据首先写入缓冲区,缓冲区填满或执行flush方法时,缓冲流将缓冲的数据写入文件。Java提供了4种缓冲流,BufferedInputStream和BufferedOutputStream用于缓冲字节流,BufferedReader和BufferedWriter用于缓冲字符流。可以创建默认大小缓冲区的缓冲流。例如:BufferedReaderin=newBufferedReader(newFileReader(datafile.txt);也可创建指定大小缓冲区的缓冲流。例如:BufferedWriterout=newBufferedWriter(newFileWriter(outdatafile.txt),100);,9.2格式化输入输出,字节流和字符流只是按字节或字符读写文件。如果要从读取特定类型的数据,例如读一个整数,则需要使用Scanner对象。在将特定类型的数据写入文件,则可使用PrintWriter或PrintStream对象完成输出。,9.2.1格式化输入,Scanner对象可以按基本数据类型从字符串或各种输入流中解析数据。,1、创建Scanner对象,Scanner类的构造方法有两种基本格式:Scanner(数据源)Scanner(数据源,字符集)创建Scanner对象的数据源可以是一个字符串、File对象、InputStream对象、InputStream子类对象、Readable对象或ReadableByteChannel对象。例如:Scannerin1=newScanner(1one2two);Scannerin2=newScanner(newFile(datafile.txt);Scannerin3=newScanner(newFileReader(datafile.txt);Scannerin4=newScanner(newFileReader(datafile.txt);Scannerin5=newScanner(newFileInputStream(datafile.txt);Scannerin6=newScanner(newBufferedReader(newFileReader(datafile.txt);,在创建访问各种流的Scanner对象时,可用一个字符串指明数据源采用的字符集,默认为本地字符集。从文件读出字节时,将其转换为指定字符集的字符。例如:Scannerin2=newScanner(newFile(datafile.txt),GB2312);/指定采用的字符集Scanner对象在不使用之后,应调用close方法将其关闭。例如:in1close();,2、从数据源解析数据,Scanner对象用一系列的next方法从数据源解析各种类型的数据:next():从数据源读取一个字符串。nextLine():将当前位置到换行符号之前的全部内容作为一个字符串返回。nextBoolean():从数据源读取一个boolean类型值。nextByte():从数据源读取一个byte类型值。nextDouble():从数据源读取一个double类型值。nextFloat():从数据源读取一个float类型值。nextInt():从数据源读取一个int类型。nextLong():从数据源读取一个long类型值。nextShort():从数据源读取一个short类型值。,在使用各种next方法读取数据时,可能会发生下列三种异常:InputMismatchException:如果下一个标记不能转换为指定类型的数据,或者超出了数据范围。NoSuchElementException:数据源中已无数据可读。IllegalStateException:Scanner对象已被关闭。这3种异常属于不检查异常,可以不捕捉处理。,9.2.2格式化输出,PrintStream和PrintWriter类提供了格式化输出方法,可用print、printf、println和format方法输出各种基本数据类型的数据,也可输出对象。printf和format方法用法相同,均可使用格式字符串来控制数据的输出格式。提示:关于格式字符串、print、printf和println方法的使用请参考2.8.1中的相关内容。println方法会在输出数据后添加一个换行符号。print、printf和format方法不自动添加换行符号,可在输出数据中包含换行符号来实现换行。PrintStream对象将数据转换为字节流输出,PrintWriter对象将数据转换为字符流输出。字符和字符串按照默认的本地字符集转换为字节。可以在创建PrintStream或PrintWriter对象,或者在printf和format方法中用Locale参数指定转换字符使用的字符集。如果PrintStream对象在创建时运行自动刷新,则在输出一个字节数组、调用println方法,或者输出一个换行符号时,可以自动调用flush方法。PrintWriter对象只会在调用println、printf或format方法时自动调用flush方法。,9.3命令行输入输出,命令行输入输出可System.in、System.out、System.err和Console对象完成。System.in代表标准输入设备,即键盘。System.out和System.err用法相同,都代表标准输出设备,即显示器。System.in和System.out的具体用法请参考第2章2.8节。Console(控制台)对象即可代表键盘,又可代表显示器,即可以完成命令行的输入和输出。System对象的console方法用于获得一个控制台对象实例,例如:Consolecon=System.console();控制台对象可以用printf和format方法输出数据,与PrintStream对象的printf和format方法相同。类似的,可以执行flush方法刷新输出,将缓存的控制台对象输出数据输出到显示器。,1、使用Reader对象输入,控制台对象的reader方法可以返回一个Reader对象,再使用Scanner对象即可完成输入。例如:Scannerinput=newScanner(con.reader();System.out.print(请输入一个字符串、一个整数和一个小数:);Stringstr=input.next();intn=input.nextInt();doublem=input.nextDouble();con.printf(刚输入的数据:n%sn%dn%fn,str,n,m);控制台对象返回的Reader对象与键盘关联,输入时按回车键结束。,2、读一行数据,控制台对象的readerLine方法可读取一行数据,即将回车之前的所有符号作为一个字符串返回。例如:System.out.print(请输入一个字符串:);Stringstr1=con.readLine();readerLine方法可以输出一个提示字符串。例如:Stringstr2=con.readLine(请输入一个字符串:);还可以为readerLine方法指定一个格式化的字符串,与printf方法参数类似。例如:Stringstr2=con.readLine(请输入%s的姓名:,汤姆);,3、密码输入,控制台对象的readPassword方法在输入数据时,不在显示器上显示输入的数据。例如:charstr3=con.readPassword(请输密码:);readPassword方法返回一个char数组。与readerLine方法类似,readPassword方法可以指定一个格式化的字符串作参数。例如:charstr3=con.readLine(请输入用户%s的密码:,汤姆);,9.4类型化输入/输出,类型化输入/输出指从数据源读/写各种基本数据类型或String类型的数据。DataInput和DataOutput接口定义了读/写数据流的方法,本节介绍这两个接口的具体实现类:DataInputStream(数据输入流)和DataOutputStream.(数据输出流)。,9.4.1数据输出流,DataOutputStream首先将数据转换为二进制形式,然后按字节输出。字符或字符串按照字符的Unicode编码输出。DataOutputStream输出的数据为二进制形式,不能直接查看。可以用DataInputStream从文件读出DataOutputStream输出的数据。,1、创建数据输出流,可用一个OutputStream对象,或OutputStream类的子类对象来创建数据输出流。例如:DataOutputStreamout=newDataOutputStream(newBufferedOutputStream(newFileOutputStream(dataoutput.txt);,2、输出数据,DataOutputStream对象可用多种方法输出数据:write(byteb,intstart,intn):将字节数组b中从下标start开始的n个元素写入输出流。参数start和n可以省略,省略时输出数组b中的全部数据。write(intn):将一个字节写入输出流。如果参数n的二进制超过一个字节,则只将最低字节写入输出流,其他字节被忽略。例如,321的二进制为101000001,用write输出321时,只将最低8位01000001输出。writeBoolean(booleanf):将一个boolean值作为一个字节写入输出流,参数f为true时输出值为1,f为false时输出值为0。writeByte(intn):将n的最低字节写入输出流。writeBytes(Strings):将字符串中的字符按顺序写入输出流,每个字符Unicode码的高8位被忽略。writeChar(intv):将一个字符(两个字节)写入输出流,先输出高8位。writeChars(Strings):将字符串中写入输出流,相等于对每个字符调用writeChar方法。,writeDouble(doublev):将一个double类型数据(8个字节)写入输出流,先输出高8位。writeFloat(floatv):将一个float类型数据(4个字节)写入输出流,先输出高8位。writeInt(intv):将一个int类型数据(4个字节)写入输出流,先输出高8位。writeLong(longv):将一个long类型数据(8个字节)写入输出流,先输出高8位。writeShort(intv):将一个short类型数据(两个字节)写入输出流,先输出高8位。writeUTF(Stringstr):将字符串按UTF-8编码格式写入输出流。先输出字符串长度,占两个字节,然后输出字符串中的字符。DataOutputStream对象会用一个计数器统计写入输出流的字节数,可用size方法返回当前已输出的字节数。,9.4.2数据输入流,DataInputStream根据数据类型,从输入流读取对应的字节数,然后将其转换为对应数据类型的数据。,1、创建数据输入流,可用一个InputStream对象或InputStream类的子类对象来创建数据输入流。例如:DataInputStreamin=newDataInputStream(newBufferedInputStream(newFileInputStream(dataoutput.txt);,2、输入数据,DataInputStream对象可用多种方法读取数据:read(byteb):从输入流读取b.length个字节存入数组。read(byteb,intstart,intn):从输入流读取n个字节,存入数组b从下标start开始的n个元素中。readBoolean():读取一个字节,若该字节为非零值,则返回true,否则返回false。readByte():读一个字节,转换为byte值。readChar():读两个字节,作为字符的Unicode码,返回该字符。readDouble():读8个字节,转换为double值。readFloat():读4个字节,转换为float值。readInt():读4个字节,转换为int值。readLong():读8个字节,转换为long值。readShort():读两个字节,转换为short值。readUTF():读一个字符串。首先读两个字节,转换为一个无符号整数,该数作为要读取的字符个数,然后读取对应个数的字符组成字符串。,9.5对象序列化,对象序列化(serialization,也称串行化)指将对象写入文件,从文件中读出对象称为序列化读出。java.io包中的ObjectOutputStream类提供了序列化概念,ObjectInputStream类提供了序列化读出功能。,9.5.1读写对象,各种基本数据类型的数组、字符串和实现了java.io.Serializable接口的类对象,都支持序列化。如果对象的成员也是一个对象,则该成员对象的类也应该实现Serializable接口,否则对象不能序列化。要保证一个对象被序列化,对象的类、基类以及所有的超类,都应该实现Serializable接口。说明:被声明为static或transient的成员不会被序列化。若对象中的某些字段不需要被序列化,则可将其声明为transient,并为其提供默认的初始值。,1、使自定义类支持序列化,用户自定义的类只需要实现Serializable接口,其对象便可序列化。Java序列化的简单指出在于,Serializable接口不包含任何方法。实现Serializable接口的类对象均按默认方式进行序列化。例如,下面是一个实现了Serializable接口的student类:publicclassstudentimplementsjava.io.Serializable,2、将对象写入文件,ObjectOutputStream类的构造方法使用一个OutputStream对象作为参数来指定要访问的文件。例如:ObjectOutputStreamout=newObjectOutputStream(newBufferedOutputStream(newFileOutputStream(objectdata.txt);该语句用一个缓冲的文件输出流对象创建对象输出流。如果为FileOutputStream构造方法指定参数是目录、路径有错或其他原因不能创建文件时,会抛出FileNotFoundException异常,应该捕捉处理或声明方法抛出该异常。FileNotFoundException类是IOException类的子类,如果处理或声明抛出了IOException异常,则可同时处理FileNotFoundException异常。ObjectOutputStream对象的writeObject方法用于将对象写入输出流。例如:studentlm=newstudent(2008001,李明,男);out.writeObject(lm);/输出自定义类对象,writeObject方法可能抛出3种异常:InvalidClassException:对象类本身定义有错时抛出该异常。NotSerializableException:对象类没有实现Serializable接口时抛出该异常。IOException:文件输出发生错误时抛出该异常。前两种异常类都是IOException类的间接子类,如果要在程序中捕捉处理这两种异常,应将对应的catch代码块写在IOException异常之前。,例如:studentlm=newstudent(2008001,李明,男);tryout.writeObject(lm);/输出自定义类对象catch(InvalidClassExceptione)e.printStackTrace();catch(NotSerializableExceptione)e.printStackTrace();catch(IOExceptione)e.printStackTrace();,3、从文件读出对象,与对象输出流类似,ObjectInputStream类的构造方法使用一个InputStream对象作为参数来指定要访问的文件。例如:ObjectInputStreamin=newObjectInputStream(newBufferedInputStream(newFileInputStream(objectdata.txt);该语句用一个缓冲的文件输入流对象创建对象输入流。如果为FileInputStream构造方法指定参数是目录、路径有错或其他原因不能创建文件时,会抛出FileNotFoundException异常,应该捕捉处理或声明方法抛出该异常。FileNotFoundException类是IOException类的子类,如果处理或声明抛出了IOException异常,则可同时处理FileNotFoundException异常。ObjectInputStream对象的readObject方法用于输入流读取对象。例如:studentlm=(student)in.readObject();,readObject方法返回一个Object类型的对象,所以应将其转换为相应的数据类型。readObject方法可能抛出5种异常:ClassNotFoundException:找不到序列化对象的类时抛出该异常。InvalidClassException:对象类本身定义有错时抛出该异常。StreamCorruptedException:序列化时会向文件写入对象的控制信息,在读出时,如果控制信息与序列化对象不匹配时抛出该异常。OptionalDataException:流中读出的是基本类型的数据,不是对象时抛出该异常。IOException:文件输入发生错误时抛出该异常。,ClassNotFoundException类是Exception类的子类,该异常应单独处理。InvalidClassException、StreamCorruptedException和OptionalDataException类是IOException类的间接,在使用catch代码块处理异常时应注意先后顺序。,9.5.2读写基本类型数据,ObjectInputStream类提供了一系列的read方法从对象输入流读取基本类型数据,这些方法与DataInputStream类提供的数据读取方法类似。ObjectOutputStream类提供了一系列的write方法向对象输出流写入基本类型数据,这些方法与DataOouputStream类提供的数据输出方法类似。,9.5.3重复序列化对象,将一个对象重复写入文件时,默认情况下,文件中只保存第一次写入的数据。重复写入对象时,即使对象数据经过了修改,也只在文件中保存指向第一次写入数据的指针。如果要保存修改之后的对象,则需要在writeObject方法之前调用reset方法。reset方法将对象输出流复位,相当于没有输出过任何内容,从而可以输出重复的对象。reset方法在文件中插入一个复位标志,对象输入流遇到复位标志时执行复位操作,从而可读出重复对象。,9.6随机读写文件,RandomAccessFile类提供了随机读写文件功能。RandomAccessFile对象维护一个文件指针,文件指针指向当前读写位置。执行read或write方法后,文件指针自动向后(文件末尾)移动。也可在执行read或write方法前,用seek方法设置文件指针位置。RandomAccessFile对象在打开文件流之后,允许将数据写入流,也可从流读出数据。在创建RandomAccessFile对象时,应指定文件访问模式。创建RandomAccessFile对象的语法格式如下:RandomAccessFileraf=newRandomAccessFile(file,mode);其中,参数file指定访问的文件,可以是一个File对象或描述文件名的字符串。参数mode是一个字符串,指定文件访问模式。可用下列访问模式字符串:r:只允许从文件读数据。若试图向文件写入数据,会产生IOException异常。rw:可读写文件。若文件不存在,会创建一个新文件。,9.7内存映射文件,内存映射文件指可以利用系统虚拟内存将文件或文件的一部分“映射”到内存。这样读写文件就像访问内存一样,大大提高文件读写速度。java.nio包中的MappedByteBuffer类用于实现内存映射。MappedByteBuffer派生自ByteBuffer类(ByteBuffer类派生自Buffer类)。,9.4.1建立内存映射,要建立内存映射,首先需要获得文件通道(FileChannel)。可用FileInputStream、FileOutputStream或RandomAccessFile类的getChannel方法获得文件通道。例如:RandomAccessFileraf=newRandomAccessFile(randomfile.txt,rw);FileChannelfc=raf.getChannel();然后,调用FileChannel类的map方法建立内存映射MappedByteBuffer。例如:MappedByteBufferbuffer=fc.map(FileChannel.MapMode.READ_WRITE,0,512);,map方法的第一个参数指定映射模式,第二个参数指定映射区域在文件中的开始位置,第三个参数指定缓冲区大小。有三种映射模式:MapMode.READ_ONLY:只能从缓冲区读数据。若试图将数据写入缓冲区,会抛出ReadOnlyBufferException异常。MapMode.READ_WRITE:可读,也可写。对缓冲区的修改最终会写入文件。MapMode.PRIVATE:私有,对缓冲区的修改不会写入文件。,9.7.2读/写缓冲区,MappedByteBuffer类继承了ByteBuffer和Buffer类的一系列get和put方法来读/写缓冲区数据。,1、读字节数组,有两种读字节数组的方法:get(bytea):根据字节数组a的长度,从缓冲区读出字节存入数组元素。get(bytea,intstart,intn):从缓冲区读出字节存入下标从start开始的数组元素中,最多读取n个字节。例如:bytea=newbyte5;buffer.get(a);buffer.get(a,2,3);,2、写字节数组,有两种方法将字节数组写入缓冲区:put(bytea):将字节数组a中的数据写入缓冲区。put(bytea,intstart,intn):将下标从start开始的n个数组元素写入缓冲区。例如:byteb=1,2,3,4,5;buffer.put(b);/输出字节数组buffer.get(b,2,3);/输出b2、b3、b4,3、按数据类型读取数据,下列方法提供了按数据类型读取数据功能:get():读一个byte类型数据。getChar():读一个char类型数据。getShort():读一个short类型数据。getInt():读一个int类型数据。getLong():读一个long类型数据。getFloat
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度物业服务合同定金条款解析与风险控制
- 2025版山地景观生态修复工程承包合同
- 2025版夫妻离婚协议书:子女抚养与财产分割详细范本
- 二零二五年度创新型借款合同模板(办公自动化版)
- 2025版瓶装矿泉水品牌授权使用合同
- 2025版防水工程验收标准合同范本
- 二零二五版国际结算电子化系统安全检测合同
- 洗浴中心会计档案管理规定
- 潜山基础知识培训课件
- 漆包线基础知识培训资料课件
- 宠物脂肪肝的诊断与治疗
- 木工分包协议书电子版
- 历年制油工题库汇编
- 小学科学教科版三年级下册全册思维导图(共24课)
- (三级)智能云服务交付工程师理论考试题库大全-中(多选题)
- 广东省深圳市龙岗区2024年八年级下学期期末英语试卷附答案
- 甲状腺术后出院健康宣教
- 现场施工环境保护应急预案
- 施工现场临电方案
- 防汛设备租赁合同
- FKYXII温控旋流风口
评论
0/150
提交评论