Java语言程序设计 课件 第13章 输入输出_第1页
Java语言程序设计 课件 第13章 输入输出_第2页
Java语言程序设计 课件 第13章 输入输出_第3页
Java语言程序设计 课件 第13章 输入输出_第4页
Java语言程序设计 课件 第13章 输入输出_第5页
已阅读5页,还剩97页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Java语言程序设计第13章输入输出

1I/O概述23主要内容Java语言程序设计(第4版)清华大学出版社2022二进制I/O流案例:文件加密解密45文本I/O流案例:统计文件行数、单词数和字符数6对象序列化7Files类操作Java语言程序设计13.1I/O概述输入/输出(I/O)是任何程序设计语言都提供的功能,Java语言从一开始就支持I/O,最初是通过java.io包中的类和接口提供支持的,之后又出现了NIO和NIO.2。概述目前Java支持流式I/O和文件I/O。流式I/O分为输入流和输出流。程序为了获得外部数据,可以在数据源(文件、内存及网络套接字)上创建一个输入流,然后用read()方法顺序读取数据。类似地,程序可以在输出设备上创建一个输出流,然后用write()方法将数据写到输出流中。所有的数据流都是单向的。使用输入流只能从中读取数据;使用输出流,只能向其写出数据,如图13-1所示。概述按照处理数据的类型分,数据流又可分为二进制流和文本流,也分别称为字节流和字符流,它们处理的信息的基本单位分别是字节和字符。java.io.File类用来表示物理磁盘上的实际文件或目录,但它不表示文件中数据。13.1.1File类应用绝对文件名是由驱动器字母、完整的路径以及文件名组成,如D:\study\Hello.txt是Windows系统下的一个绝对文件名。相对文件名是相对于当前工作目录的。例如,Hello.txt是一个相对文件名。如果当前工作目录是D:\study,绝对文件名是D:\study\Hello.txt。importjava.io.*;publicclassFileDemo{publicstaticvoidmain(String[]args){varfile=newFile("Hello.txt");//此时文件还不存在!}}编译并运行该程序,当查看当前目录,找不能到Hello.txt文件。这说明创建一个File实例并不是创建实际的文件,而仅仅创建一个表示文件的对象。如果要创建实际的文件,可使用下面代码:try{booleansuccess=false;varfile=newFile("Hello.txt");System.out.println(file.exists());//输出文件是否存在success=file.createNewFile();

//创建文件是否成功System.out.println(success);System.out.println(file.exists());//输出文件是否存在}catch(IOExceptione){System.out.println(e.toString());}下面是File类最常用操作方法。publicbooleanexists():测试File对象是否存在。publiclonglength():返回指定文件的字节长度,文件不存在时返回0。publicbooleancreateNewFile():当文件不存在时,创建一个空文件时返回true,否则返回false。publicbooleanrenameTo(FilenewName):重新命名指定的文件对象,正常重命名时返回true,否则返回false。publicbooleandelete():删除指定的文件。若为目录,当目录为空才能删除。publiclonglastModified():返回文件最后被修改的日期和时间,它计算的是从1970年1月1日0时0分0秒开始的毫秒数。13.1.1File类应用文件通常可以分为文本文件和二进制文件。文本文件(textfile)是包含字符序列的文件,可以使用文本编辑器查看或通过程序阅读。内容必须按二进制序列处理的文件称为二进制文件(binaryfile)。13.1.2文本I/O与二进制I/O实际上,计算机并不区分二进制文件与文本文件。所有的文件都是以二进制形式来存储的,因此,从本质上说,所有的文件都是二进制文件。对于文本I/O而言,在写入一个字符时,Java虚拟机会将字符的统一码转换为文件指定的编码,在读取字符时,将文件指定的编码转换为统一码。13.1.2文本I/O与二进制I/O使用文本I/O将字符串“123”写入文件,那么每个字符的二进制编码都会写入到文件。二进制I/O不需要进行转换。如果使用二进制I/O向文件写入一个数据,就是将内存中的值复制到文件中。13.1.2文本I/O与二进制I/O例如,一个byte类型的数值123在内存中表示为01111011,将它写入文件也是01111011。使用二进制I/O读取一个字节时,就会从输入流中读取一个字节的二进制编码。Java语言程序设计13.2二进制I/O流6.1.1publicintread()publicintread(byte[]b)publicvoidclose()InputStream类是二进制输入流的根类,它有多个子类。InputStream类和OutputStream类Java语言程序设计(第4版)

QQ群:2886394866.1.1

publicvoidwrite(intb)publicvoidwrite(byte[]b)publicvoidclose()OutputStream类是二进制输出流的根类,它有多个子类。Java语言程序设计(第4版)

QQ群:288639486InputStream类和OutputStream类FileInputStream类和FileOutputStream类用来实现文件的输入输出处理。13.2.2FileOutputStream类和FileInputStream类FileInputStream类和FileOutputStream类都实现了java.lang.AutoClosable接口,因此可以在try-with-resources语句中使用,当流使用完自动将它们关闭。FileOutputStream类的常用构造方法如下:FileOutputStream(Stringname):用表示文件的字符串创建文件输出流对象。FileOutputStream(Stringname,booleanappend):用表示文件的字符串创建文件输出流对象。如果append参数为true,则指明打开的文件输出流不覆盖原来的内容,而是从文件末尾写入新内容,否则覆盖原来的文件内容。FileOutputStream(Filefile):用File对象创建文件输出流对象。13.2.2FileOutputStream类和FileInputStream类FileInputStream类的两个常用的构造方法如下:

FileInputStream(Stringname):用表示文件的字符串创建文件输入流对象。FileInputStream(Filefile):用File对象创建文件输入流对象。13.2.2FileOutputStream类和FileInputStream类若指定的文件不存在,则产生FileNotFoundException异常,它是检查异常,必须捕获或声明抛出。也可以先创建File对象,然后测试该文件是否存在,若存在再创建文件输入流。publicstaticvoidmain(String[]args){varoutputFile=newFile("output.dat");try(varout=newFileOutputStream(outputFile);){for(vari=0;i<10;i++){intx=(int)(Math.random()*90)+10;out.write(x);}out.flush();//刷新输出流System.out.println("已向文件写入10个两位数!");}catch(IOExceptione){System.out.println(e.toString());}}程序13.1WriteByteDemo.java

publicstaticvoidmain(String[]args){

varinputFile=newFile("output.dat");

try(

varin=newFileInputStream(inputFile);){

intc=in.read();

while(c!=-1){System.out.print(c+"");c=in.read();

}}catch(IOExceptione){System.out.println(e.toString());}

}程序13.2ReadByteDemo.javaBufferedInputStream的构造方法如下:BufferedInputStream(InputStreamin):使用参数in指定的输入流对象创建一个缓冲输入流。

BufferedInputStream(InputStreamin,intsize):使用参数in指定的输入流对象创建一个缓冲输入流,并且通过size参数指定缓冲区大小,默认为512个字节。使用上面两个类,可以把输入输出流包装成具有缓冲功能的流,从而提高输入输出的效率。13.2.3BufferedOutputStream类和BufferedInputStream类BufferedOutputStream为缓冲输出流,BufferedInputStream为缓冲输入流,这两个类用来对流实现缓冲功能。使用缓冲流可以减少读写数据的次数,加快输入输出的速度。13.2.3BufferedOutputStream类和BufferedInputStream类BufferedOutputStream类的构造方法如下:BufferedOutputStream(OutputStreamout):使用参数out指定的输出流对象创建一个缓冲输出流。BufferedOutputStream(OutputStreamout,intsize):使用参数out指定的输出流对象创建一个缓冲输出流,并且通过size参数指定缓冲区大小,默认为512个字节。DataOutputStream类和DataInputStream类分别是数据输出流和数据输入流。使用这两个类可以实现基本数据类型的输入输出。这两个类的构造方法如下:13.2.4DataOutputStream类和DataInputStream类DataOutputStream(OutputStreamoutstream):参数outstream是字节输出流对象。DataInputStream(InputStreaminstream):参数instream是字节输入流对象。varinFile=newDataInputStream(newBufferedInputStream(newFileInputStream("input.dat")));varoutFile=newDataOutputStream(newBufferedOutputStream(newFileOutputStream("output.dat")));13.2.4DataOutputStream类和DataInputStream类DataOutputStream类定义的常用方法如下所示。publicvoidwriteByte(intv):将整数v低的8位写入输出流,忽略高24位。publicvoidwriteInt(intv):向输出流写一个4个字节的整数。publicvoidwriteLong(longv):向输出流写一个8个字节的长整数。publicvoidwriteDouble(doublev):向输出流写一8个字节的double型浮点数。publicvoidwriteBytes(Strings):将参数字符串每个字符的低位字节按顺序写到输出流中。publicvoidwriteUTF(Strings):将参数字符串字符按UTF-8的格式写出到输出流中。UTF-8格式的字符串中每个字符可能是1个、2个或3个字节,另外字符串前要加2个字节存储字符数量。13.2.4DataOutputStream类和DataInputStream类DataInputStream类定义的常用方法如下所示。publicbytereadByte():从输入流读一个字节并返回该字节。publicintreadInt():从输入流读4个字节,返回一个int型值。publiclongreadLong():从输入流读8个字节,返回一个long型值。publicdoublereadDouble():从输入流读8个字节,返回一个double型值。publicStringreadLine():从输入流读下一行文本。该方法已被标记为不推荐使用。publicStringreadUTF():从输入流读UTF-8格式的字符串。编写程序,使用DataOutputStream流将数据写入到文件中,这里还将数据流包装成缓冲流。之后,使用DataInputStream流从文件中读取数据并在控制台输出。数据I/O流的应用

//向文件中写数据

try(FileOutputStreamoutput=newFileOutputStream("data.dat");DataOutputStreamdataOutStream=newDataOutputStream(

newBufferedOutputStream(output));

){dataOutStream.writeDouble(123.456);dataOutStream.writeInt(100);dataOutStream.writeUTF("Java语言");}catch(IOExceptione){e.printStackTrace();

}程序13.3DataStreamDemo.java

//从文件中读取数据

try(FileInputStreaminput=newFileInputStream("data.dat");DataInputStreamdataInStream=newDataInputStream(

newBufferedInputStream(input));

){while(dataInStream.available()>0){

doubled=dataInStream.readDouble();

inti=dataInStream.readInt();Strings=dataInStream.readUTF();System.out.println("d="+d);System.out.println("i="+i);System.out.println("s="+s);

}}catch(IOExceptione){e.printStackTrace();

}PrintStream类为打印各种类型的数据提供了方便。PrintStream类定义了多个print()和println()方法,可以打印输出各种类型的数据,这些方法都是把数据转换成字符串,然后输出。如果输出到文件中则可以用记事本浏览。println()方法输出后换行,print()方法输出后不换行。13.2.5PrintStream类当把对象传递给这两个方法时则先调用对象的toString()方法将对象转换为字符串形式,然后输出。在前面章节大量使用的System.out对象就是PrintStream类的一个实例,用于向控制台输出数据。Java在System类中定义了标准输出流out,标准输入流in以及标准错误输出流err,如下所示。13.2.6标准输入输出流publicstaticfinaljava.io.PrintStreamout;publicstaticfinaljava.io.InputStreamin;publicstaticfinaljava.io.PrintStreamerr;System.in是InputStream类的实例。可以使用read()方法从键盘上读取字节,也可以将它包装成数据流读取各种类型的数据和字符串。System.out和System.err是PrintStream类的实例,可以使用该类定义的方法输出各种类型数据。6.1.1问题描述编写程序,随机生成10个1000到2000之间的整数,将它们写到一个文件data.dat中,然后从该文件中读出这些整数,要求使用DataInputStream和DataOutputStream类实现。课堂讨论与训练Java语言程序设计(第4版)

QQ群:288639486Java语言程序设计13.3案例:文件加密解密编写一个简单的文件加密、解密程序。文件加密、解密有多种方法,本案例使用一种简单的算法,对文件的内容使用“异或”运算进行加密后保存到指定的文件中。要对文件解密,读取文件中的加密内容,再次使用“异或”运算解密得到原文件内容。文件加密解密本案例使用“异或”运算对文件中字节进行加密、解密的原理可以描述如下:按位“异或”运算符的运算规则是:两个操作数中,如果相应位相同,则结果为0,否则为1,例如:00101010^00010111=00111101“异或”运算符的特点是:用同一个数b对操作数a进行两次“异或”运算,结果仍然为原值a。就是,如果c=a^b,那么a=c^b,即用同一个数b对数a进行两次“异或”运算的结果又是数a。利用“异或”运算的这个性质,可以实现简单的字节加密、解密操作。文件加密解密(1)程序首先要求用户输入要加密的文件名、加密后的文件名以及加密使用的秘钥,也就是要在读取的字节上做“异或”运算的整数。(2)使用FileInputStream和FileOutputStream创建输入流(源文件)和输出流(加密文件),从源文件读取每个字节然后对它做“异或”运算,将结果写入加密的文件。文件加密解密(3)文件解密的过程与加密的过程类似。使用FileInputStream和FileOutputStream创建输入流(要解密的文件)和输出流(解密后文件),从输入流读取每个字节然后对它做“异或”运算,将结果写入解密后的文件。这里要注意,解密使用的秘钥需与加密使用的秘钥相同,否则得不到源文件。varinput=newScanner(System.in);StringsourceFile=null;StringsecretFile=null;varkeyValue=0;System.out.print("请输入源文件名:");sourceFile=input.nextLine();System.out.print("请输入加密文件名:");secretFile=input.nextLine();System.out.print("请输入秘钥:");keyValue=input.nextInt();程序13.4FileEncription.javavarsrcFile=newFile(sourceFile);varencFile=newFile(secretFile);if(!srcFile.exists()){System.out.println("源文件不存在!");System.exit(0);}if(!encFile.exists()){System.out.println("创建加密文件!");encFile.createNewFile();}try(varfis=newFileInputStream(srcFile);varfos=newFileOutputStream(encFile); ){vardataOfFile=fis.read();while(dataOfFile!=-1){

dataOfFile=dataOfFile^keyValue;fos.write(dataOfFile);dataOfFile=fis.read();}}

varinput=newScanner(System.in);StringsecretFile=null;StringresultFile=null;

varkeyValue=0;System.out.print("请输入要解密文件:");secretFile=input.nextLine();System.out.print("请输入解密后文件名:");resultFile=input.nextLine();System.out.print("请输入秘钥:");keyValue=input.nextInt();程序13.5FileDecription.java

varencFile=newFile(secretFile);

vardecFile=newFile(resultFile);

if(!encFile.exists()){System.out.println("解密的文件不存在!");System.exit(0);

}

if(!decFile.exists()){//System.out.println("创建目标文件!");decFile.createNewFile();

}

try(

varfis=newFileInputStream(encFile);

varfos=newFileOutputStream(decFile);

){

vardataOfFile=fis.read();

while(dataOfFile!=-1){dataOfFile=dataOfFile^keyValue;fos.write(dataOfFile);dataOfFile=fis.read();

}

}Java语言程序设计13.4文本I/O流文本I/O流以字符为基本单位,也叫字符I/O流。抽象类Reader和Writer分别是文本输入流和输出流的根类。概述概述Writer类是字符输出流的根类,定义的常用方法有:publicvoidwrite(intc):向输出流中写一个字符,实际是将int型的c的低16位写入输出流。publicvoidwrite(Stringstr):把字符串str写入输出流中。publicvoidclose():关闭输出流。13.4.1Reader类和Writer类Reader类是文本输入流的根类,定义的常用方法有:

publicintread():读取一个字符,返回范围为0到65535之间int型值,如果到达流的末尾返回-1。publicvoidclose():关闭输入流。FileReader类构造方法有:FileReader(StringfileName)FileReader(Filefile)13.4.2FileWriter类和FileReader类FileWriter类构造方法有:

FileWriter(StringfileName)

FileWriter(Filefile)FileWriter(StringfileName,booleanappend)下面的FileCopyDemo.java程序使用FileReader和FileWriter将文件input.txt(在项目跟目录下)的内容复制到output.txt文件中。13.4.2FileWriter类和FileReader类FileinputFile=newFile("input.txt");FileoutputFile=newFile("output.txt");try(FileReaderin=newFileReader(inputFile);FileWriterout=newFileWriter(outputFile);

){intc=in.read();while(c!=-1){out.write(c);c=in.read();

}}catch(IOExceptione){System.out.println(e.toString());

}程序13.4FileCopyDemo.javaBufferedReader类和BufferedWriter类分别实现具有缓冲功能的字符输入输出流。这两个类用来将其他的字符流包装成缓冲字符流,以提高读写数据的效率。BufferedReader类的构造方法如下:publicBufferedReader(Readerin):用默认的缓冲区大小创建缓冲字符输入流。publicBufferedReader(Readerin,intsz):用指定的缓冲区大小创建缓冲字符输入流。13.4.3BufferedReader类和BufferedWriter类下面代码创建了一个BufferedReader对象:varin=newBufferedReader(newFileReader("input.txt"));BufferedWriter类的构造方法如下:BufferedWriter(Writerout):用默认的缓冲区大小创建缓冲字符输出流。BufferedWriter(Writerout,intsz):用指定的缓冲区大小创建缓冲字符输出流。13.4.3BufferedReader类和BufferedWriter类通常Writer直接将输出发送到基本的字符或字节流,建议在Writer上(如FileWriter和OutputStreamWriter)包装BufferedWriter,例如:varbr=newBufferedWriter(newFileWriter("output.txt"));StringfileName="article.txt";

intsum=0;

try(FileReaderinFile=newFileReader(fileName);BufferedReaderreader=newBufferedReader(inFile);

){StringaLine=reader.readLine();

while(aLine!=null){String[]words=aLine.split("[,.]");sum=sum+words.length;aLine=reader.readLine();

}}catch(IOExceptione){System.out.println(e.toString());

}System.out.println("单词数量为:"

+sum);程序13.5WordsCount.javaPrintWriter类实现字符打印输出流,它的构造方法如下:PrintWriter(Writerout):使用参数指定的输出流对象out创建一个打印输出流。PrintWriter(Writerout,booleanautoFlush):如果autoFlush指定为true,则在输出之前自动刷新输出流。13.4.4PrintWriter类PrintWriter类定义的常用方法如下。publicvoidprintln(booleanb):输出一个boolean型数据。publicvoidprintln(Strings):输出一个String型数据。publicvoidprintln(Objectobj):将obj转换成String型数据,然后输出。下面程序随机产生10个100到200之间的整数,然后使用PrintWriter对象输出到文件number.txt中。13.4.4PrintWriter类for(vari=0;i<10;i++){varnum=(int)(Math.random()*101)+100;pw.println(num);}varfileName="number.txt"; varout=newFileWriter(newFile(fileName));varpw=newPrintWriter(out,true);//向文件中随机写入10个随机整数for(vari=0;i<10;i++){varnum=(int)(Math.random()*101)+100;pw.println(num);}pw.close();程序13.6PrintWriterDemo.java//从文件中读出10个整数varin=newFileReader(newFile(fileName));varreader=newBufferedReader(in);varaLine=reader.readLine();while(aLine!=null){System.out.print(aLine+"");aLine=reader.readLine();}reader.close();该程序运行后在项目目录下创建一个number.txt文本文件,并且写入10个整数,该文件可以用记事本打开。使用Scanner类从键盘读取数据,这是在创建Scanner对象时将标准输入设备System.in作为其构造方法的参数。使用Scanner还可以关联文本文件,从文本文件中读取数据。13.4.5使用Scanner对象Scanner类的常用的构造方法有:publicScanner(Stringsource):用指定的字符串构造Scanner对象,以便从中读取数据。publicScanner(InputStreamsource):用指定的输入流构造一个Scanner对象,以便从中读取数据。Scanner类的常用方法如下所示:publicbytenextByte():读取下一个标记并将其解析成byte型数。publicintnextInt():读取下一个标记并将其解析成int型数。publicdoublenextDouble():读取下一个标记并将其解析成double型数。publicStringnext():读取下一个标记并将其解析成字符串。publicStringnextLine():读取当前行作为一个String型字符串。13.4.5使用Scanner对象varfile=newFile("number.txt");try(varinput=newFileInputStream(file);varsc=newScanner(input)){while(sc.hasNextInt()){ vartoken=sc.nextInt(); System.out.println(token);}}catch(IOExceptione){e.printStackTrace();} 程序13.7TextFileDemo.javaJava语言程序设计13.5案例:统计文件行数、单词数和字符数经常需要对文本文件分析,比如查找有关内容,进行某种统计等。本案例要求编写程序,统计一个英文文本文件中的字符数、单词数和行数。单词由空格和逗号、句号、分号和感叹号这几个个标点符号分隔,文件名由键盘读入。统计文件行数、单词数和字符数(1)创建Scanner对象,从键盘读取要统计的源文件名,并判断文件是否存在,存在继续,不存在则强制程序结束。(2)创建FileReader和BufferedReader对象,使用readLine()方法从指定的文件读取字符串进行解析。(3)对每一行的字符串,用String的length()方法计算字符数,再使用String类的split()方法根据置分隔符来解析所包含的单词数。

varinput=newScanner(System.in);

varfilename="";System.out.print("请输入文本文件名:");filename=input.nextLine();

varfile=newFile(filename);

if(!file.exists()){System.out.println("您输入的文件不存在!");System.exit(0);

}程序13.8WordsCount.java

try(

varfis=newBufferedReader(newFileReader(file));

){

varcharNums=0;

varwordsNums=0;

varlineNums=0;

varaLine=fis.readLine();

while(aLine!=null){charNums=charNums+aLine.length();

varwords=aLine.split("[,;.!]");//5个符号wordsNums=wordsNums+words.length;lineNums=lineNums+1;aLine=fis.readLine();

}

System.out.println("文件="

+filename);System.out.println("共有行数="

+lineNums+"行");System.out.println("单词数="

+wordsNums+"个"

);System.out.println("总共字符数="

+charNums+"个");}catch(IOExceptionioe){ioe.printStackTrace();

}Java语言程序设计13.6对象序列化对象的寿命通常随着创建该对象的程序的终止而终止。有时可能需要将对象的状态保存下来,在需要时再将其恢复。对象状态的保存和恢复可以通过对象I/O流实现。13.6.1对象序列化与对象流将程序中的对象输出到外部设备(如磁盘、网络)中,称为对象序列化(serialization)。反之,从外部设备将对象读入程序中称为对象反序列化(deserialization)。一个类的对象要实现对象序列化,必须实现java.io.Serializable接口,该接口的定义如下。publicinterfaceSerializable{}Serializable只是标识性接口,其中没有定义任何方法。13.6.1对象序列化与对象流一个类的对象要序列化,除了必须实现Serializable接口外,还需要创建对象输出流和对象输入流,然后,通过对象输出流将对象状态保存下来,通过对象输入流恢复对象的状态。在java.io包中定义了两个类ObjectInputStream和ObjectOutputStream,分别称为对象输入流和对象输出流。若将对象写到外部设备需要建立ObjectOutputStream类的对象,构造方法为:publicObjectOutputStream(OutputStreamout)参数out为一个字节输出流对象。13.6.2向ObjectOutputStream中写入对象创建了对象输出流后,就可以调用它的writeObject()方法将一个对象写到流中,该方法格式为:publicfinalvoidwriteObject(Objectobj)throwsIOException若写出的对象不是可序列化的,该方法会抛出NotSerializableException异常。由于ObjectOutputStream类实现了DataOutput接口,该接口中定义多个方法用来写入基本数据类型,如writeInt()、writeFloat()及writeDouble()等,可以使用这些方法向对象输出流中写基本数据类型。13.6.2向ObjectOutputStream中写入对象下面代码将一些数据和对象写到对象输出流中。oos.writeInt(2022);oos.writeObject("你好");oos.writeObject(LocalDate.now());若要从外部设备上读取对象,需建立ObjectInputStream对象,该类的构造方法为:publicObjectInputStream(InputStreamin)参数in为字节输入流对象。13.6.3从ObjectInputStream中读取对象通过调用ObjectInputStream类的方法readObject()方法可以读取一个对象,该方法的声明格式为:publicfinalObjectreadObject()throwsIOException在使用readObject()方法读出对象时,其类型和顺序必须与写入时一致。ObjectInputStream类实现了DataInput接口,该接口中定义了读取基本数据类型的方法,如readInt()、readFloat()及readDouble(),使用这些方法可以从ObjectInputStream流中读取基本数据类型。13.6.3从ObjectInputStream中读取对象下面代码在InputStream对象上建立一个对象输入流对象。varfis=newFileInputStream("data.ser");varoip=newObjectInputStream(fis);inti=ois.readInt();vartoday=(String)ois.readObject();vardate=(LocalDate)ois.readObject();下面的例子说明如何实现对象的序列化和反序列化,这里的对象是Customer记录类型的对象,它实现了Serializable接口。关于记录类型,请参阅11.1节。示例:对象序列化和反序列化程序13.8Customer.javapackagecom.boda.xy;importjava.io.Serializable;publicrecordCustomer(intid,Stringname,Stringaddress)implementsSerializable{}varcustomer=newCustomer(101,"刘明","北京市海淀区");vartoday=LocalDate.now();//序列化try(varoutput=newFileOutputStream("D:\\study\\customer.dat"); varoos=newObjectOutputStream(output)){ oos.writeObject(customer);//写入一个客户对象 oos.writeObject(today);//写入一个日期对象}catch(IOExceptione){ e.printStackTrace();}程序13.9ObjectSerializeDemo.javatry(varinput=newFileInputStream("D:\\study\\customer.dat");varois=newObjectInputStream(input)){while(true){ try{ customer=(Customer)ois.readObject(); System.out.println("客户号:"+customer.id()); System.out.println("姓名:"+()); System.out.println("地址:"+customer.address());today=(LocalDate)ois.readObject(); System.out.println("日期:"+today); }catch(EOFExceptione){}如果数组中的所有元素都是可序列化的,这个数组就是可序列化的。一个完整的数组可以用writeObject()方法存入文件,之后用readObject()方法读取到程序中。13.6.4序列化数组下面程序将一个有5个元素的int型数组和一个有3个元素的String型数组存储到文件中,然后将它们从文件中读取出显示在控制台上。try{int[]numbers={1,2,3,4,5};String[]cities={"北京","上海","广州"};//序列化try(varoutput=newFileOutputStream("array.dat",true);varoos=newObjectOutputStream(output);){ oos.writeObject(numbers);//将numbers数组写入文件 oos.writeObject(cities);//将cities数组写入文件}catch(IOExceptione){e.printStackTrace(); }程序13.10ArraySerialDemo.javatry(//反序列化varinput=newFileInputStream("array.dat");varois=newObjectInputStream(input);){//读取数组对象int[]newNumbers=(int[])ois.readObject();String[]newStrings=(String[])ois.readObject();for(intn:newNumbers) System.out.print(n+"");System.out.println();for(Strings:newStrings) System.out.print(s+"");Java语言程序设计13.7Files类操作为了增强JavaI/O功能,在新的JDK中增加了一些新的API处理I/O操作,主要包括java.nio包及其子包,以及java.nio.file包及其子包。概述java.nio.file.Files类是一个功能非常强大的类。该类定义了大量的静态方法用来读、写和操纵文件和目录。Files类主要操作Path对象,下面首先介绍Path接口,然后学习Files在Java7之前,用File对象表示文件和目录。由于使用File类存在着许多不足,因此在Java7中应使用java.nio.file.Path接口代替File。Path对象在文件系统中表示文件或目录。它表示一个路径,可以是一个文件、一个目录,它还可以表示一个根目录13.7.1Path对象在Windows系统中,Path对象使用Windows语法表示(如,D:\study\com\demo)。有多种方式创建和操作Path实例,可以把一个Path对象追加到另一个Path对象上、抽取Path对象部分内容、与另一个Path对象比较等。Path实例包含确定文件或目录位置的信息。在创建Path实例时,通常要提供一系列名称,如根元素或文件名等。一个Path可以只包含路径名或文件名。可以使用Paths(注意是复数)类的get()方法创建Path对象:1.创建Path实例varp1=Paths.get("D:\\study\\com\\Hello.java");varp2=Paths.get(args[0]);varp3=Paths.get(URI.create("file:///users/joe/FileTest.java"));Path对象可以看做是一个名称序列,每一级目录可以通过索引指定。目录结构的最顶层索引为0,目录结构的最底层元素索引是n-1,n是总层数。例如,getName(0)方法将返回最顶层目录名称。下面代码演示了Path接口的几个方法。2.检索路径信息varpath=Paths.get("D:\\study\\user\\report.txt");System.out.println("toString:"+path.toString());System.out.println("getFileName:"+path.getFileName());System.out.println("getName(0):"+path.getName(0));System.out.println("getNameCount:"+path.getNameCount());System.out.println("subpath(0,2):"+path.subpath(0,2));System.out.println("getParent:"+path.getParent());System.out.println("getRoot:"+path.getRoot());Files类提供了下面的方法创建、删除目录和文件:13.7.2创建和删除目录及文件staticPathcreateDirectory(Pathdir,FileAttribute<?>…attrs):创建由dir指定的目录,如果创建的目录已经存在,该方法将抛出FileAlreadyExistsException异常。staticPathcreateFile(Pathfile,FileAttribute<?>…attrs)

staticvoiddelete(Pathpath)staticvoiddeleteIfExists(Pathpath)try{Files.delete(path);}catch(NoSuchFileExceptionx){System.out.println("Nosuchfile"+path);}catch(DirectoryNotEmptyExceptionx){System.err.format("Thedirectoryisnotempty");}catch(IOExceptionx){//文件许可问题在此捕获System.err.println(x);}可以使用Files类的方法检查Path对象表示的文件或目录是否存在、是否可读、是否可写、是否可执行等。13.7.3文件属性操作staticbooleanexists(Pathpath,LinkOption…options)staticbooleannotExists(Pathpath,LinkOption…options)staticbooleanisReadable(Pathpath)staticbooleanisWritable(Pathpath)staticbooleanisExecutable(Pathpath)booleanisRegularFile(Pathpath,LinkOption...options)Files类中包含了下面一些方法获得或设置文件的一个属性。13.7.3文件属性操作staticlongsize(Pathpath):返回指定文件的字节大小。staticbooleanisDirectory(Pathpath,LinkOption…options)staticbooleanisHidden(Pathpath)staticFileTimegetLastModifiedTime(Pathpath,LinkOption...options)staticPathsetLastModifiedTime(Pathpath,FileTime)staticUserPrincipalgetOwner(Pathpath,LinkOption...options)6.1.1Java语言程序设计(第4版)

QQ群:288639486复制、移动目录与文件使用Files类的copy()方法可以复制文件和目录。staticPathcopy(Pathsource,Pathtarget,CopyOption…options)StandardCopyOption枚举是CopyOption接口的一个实现:ATOMIC_MOVECOPY_ATTRIBUTESREPLACE_EXISTING6.1.1Java语言程序设计(第4版)

QQ群:288639486复制、移动目录与文件Pathsource=Paths.get("D:\\study\\demo\\report.txt"),target=Paths.get("D:\\study\\demo\\backup.txt");try{Files.copy(source,target,StandardCopyOption.REPLACE_EXISTING);}catch(NoSuchFileExceptionnse){nse.printStackTrace();}catch(IOExceptionioe){ioe.printStackTrace();}6.1.1Java语言程序设计(第4版)

QQ群:288639486复制、移动目录与文件使用Files类的move()方法可以移

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论