




已阅读5页,还剩26页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2020/5/27,1,第九章输入、输出流,本章导读文件文件字节流和文件字符流缓冲流数组流和字符串流数据流对象流序列化和对象克隆随机读写流使用Scanner类解析文件文件锁,2020/5/27,2,输入流、输出流概述,I/O流提供一条通道程序,可以使用这条通道读取“源”中的数据,或把数据送到“目的地”。I/O流中的输入流的指向称为源,程序从指向源的输入流中读取源中的数据(如图9.1所示意);输出流的指向称为目的地,程序通过向输出流中写入数据把信息传递到目的地(如图9.2所示意)。程序的源和目的地也可以是键盘、鼠标、内存或显示器窗口。,2020/5/27,3,I/O流库提供的4个重要的abstract类,Java的I/O流库提供大量的流类(在包java.io中),其中有4个重要的abstract类:InputStream字节输入流Reader字符输入流OutputStream字节输出流Writer字符输出流InputStream和Reader类为其子类提供了重要的读取数据的read()方法.OutputStream和Writer类为其子类提供了重要的写入数据的write()方法。,2020/5/27,4,9.1文件,多流的读写与文件有关。Java使用File类创建的对象来获取文件本身的一些信息,如文件所在的目录、文件的长度、文件读写权限等,文件对象并不涉及对文件的读写操作。创建一个File对象的构造方法有3个:File(Stringfilename);File(StringdirectoryPath,Stringfilename);File(Filef,Stringfilename);其中filename是文件名字,directoryPath是文件的路径,f是一个目录。使用File(Stringfilename)创建文件时,该文件被认为是与当前应用程序在同一目录中。,2020/5/27,5,1文件的属性,使用File类的下列方法可以获取文件本身的一些信息:publicStringgetName()获取文件的名字。publicbooleancanRead()判断文件是否是可读的。publicbooleancanWrite()判断文件是否可被写入。publicbooleanexits()判断文件是否存在。publiclonglength()获取文件的长度(单位是字节)。publicStringgetAbsolutePath()获取文件的绝对路径。publicStringgetParent()获取文件的父目录。publicbooleanisFile()判断文件是否是一个正常文件,而不是目录。publicbooleanisDirectroy()判断文件是否是一个目录。publicbooleanisHidden()判断文件是否是隐藏文件。publiclonglastModified()获取文件最后修改的时间(时间是从1970年午夜至文件最后修改时刻的毫秒数。,2020/5/27,6,2目录,1)创建目录publicbooleanmkdir()创建一个目录,创建成功返回true,否则返回false。2)列出目录中的文件(如果File对象是一个目录)publicStringlist()用字符串形式返回目录下的全部文件。publicFilelistFiles()用File对象形式返回目录下的全部文件。File类的下述两个方法可以列出指定类型的文件:publicStringlist(FilenameFilterobj)该方法用字符串形式返回目录下的指定类型的所有文件。publicFilelistFiles(FilenameFilterobj)该方法用File对象返回目录下的指定类型所有文件。FilenameFilter是一个接口,该接口有一个方法:publicbooleanaccept(Filedir,Stringname);使用list()方法时,需向该方法传递一个实现FilenameFilter接口的对象。list()方法执行时,参数不断回调接口方法accept(Filedir,Stringname),参数name被实例化目录中的一个文件名,参数dir为调用list的当前对象,当接口方法返回true时,list()方法就将目录dir中的文件存放到返回的数组中。,2020/5/27,7,3文件的创建与删除,对于Filef=newFile(C:myletter,letter.txt);如果C:myletter目录中没有名字为letter.txt的文件,文件对象f调用方法publicbooleancreateNewFile()可以在C:myletter目录中建立一个名字为letter.txt的文件。文件对象调用方法publicbooleandelete()可以删除当前文件,如f.delete();例9-1列出了D:ch9目录下java源文件的名字及其大小,并删除了D:ch9中的一个java源文件。,2020/5/27,8,4运行可执行文件,使用java.lang包中的Runtime类,执行一个本地机上的可执行文件。首先使用Runtime类声明一个对象,如Runtimeec;然后使用该类的静态getRuntime()方法创建这个对象:ec=Runtime.getRuntime();ec可以调用exec(Stringcommand)方法打开本地的可执行文件或执行一个操作。例9-2中,Runtime对象打开Windows平台上的绘图程序和记事本程序。,2020/5/27,9,9.2文件字节流,1FileInputStream类FileInputStream类是InputStream的子类,称为文件字节输入流,按字节读取文件中的数据。该类的所有方法都是从InputStream类继承来的。构造方法:FileInputStream(Stringname)FileInputStream(Filefile)构造方法参数指定的文件称为输入流的源,输入流通过使用read()方法从输入流读出源中的数据。建立一个文件输入流对象,代码如下:tryFileInputStreamins=newFileInputStream(myfile.dat);catch(IOExceptione)System.out.println(e);read()方法的形式:intread();从输入流中顺序读取单个字节的数据intread(byteb)和intread(byteb,intoff,intlen)把多个字节读到一个字节数组中,返回实际读取的字节个数。参数off指定read()方法把数据存放在字节数组b中的位置,参数len指定该方法将读取的最大字节数。FileInputStream流顺序地读取文件,只要不关闭流,每次调用read()方法就顺序地读取文件中其余的内容,直到文件的末尾或流被关闭。,2020/5/27,10,2FileOutputStream类,FileOutputStream提供了基本的文件写入能力,是OutputStream的子类,称为文件字节输出流。文件字节输出流按字节将数据写入到文件中.构造方法:FileOutputStream(Stringname)FileOutputStream(Filefile)FileOutputStream(Stringname,booleanappend)FileOutputStream(Filefile,booleanappend)构造方法参数指定的文件称为输出流的目的地。输出流使用write()方法把数据写入输出流到达目的地。publicvoidwrite(byteb)写b.length个字节到输出流。publicvoid.write(byteb,intoff,intlen)从给定字节数组中起始于偏移量off处写len个字节到输出流,参数b是存放了数据的字节数组。只要不关闭流,每次调用writer()方法就顺序地向文件写入内容,直到流被关闭例9-3中,首先将“欢迎welcom”写入到文件“hello.txt”中,然后再读取该文件中的内容。,2020/5/27,11,9.3文件字符流,1FileReader类FileReader类是Reader的子类,称为文件字符输入流。文件字符输入流按字符读取文件中的数据。构造方法:FileReader(Stringname)FileReader(Filefile)构造方法参数指定的文件称为输入流的源,输入流通过使用read()方法从输入流读出源中的数据。intread()输入流调用该方法从源中读取一个字符。该方法返回一个整数(065535之间的一个整数,Unicode字符值),如果未读出字符就返回1。intread(charb)输入流调用该方法从源中读取b.length个字符到字符数组b中,返回实际读取的字符数目。如果到达文件的末尾,则返回-1。intread(charb,intoff,intlen)输入流调用该方法从源中读取len个字符并存放到字符数组b中,返回实际读取的字符数目。如果到达文件的末尾,则返回-1。其中,参数off指定该方法从字符数组b中的什么地方存放数据。,2020/5/27,12,2FileWriter类,FileWriter提供了基本的文件写入能力。FileWriter类是Writer的子类,称为文件字符输出流。文件字符输出流按字符将数据写入到文件中.构造方法:FileWriter(Stringname);FileWriter(Filefile);FileWriter(Stringname,booleanappend);FileWriter(Filefile,booleanappend);构造方法参数指定的文件称为输出流的目的地。输出流使用write()方法把数据写入输出流到达目的地。publicvoidwrite(charb)写b.length个字符到输出流publicvoid.write(charb,intoff,intlen)从给定字符数组中起始于偏移量off处写len个字符到输出流,参数b是存放了数据的字符数组voidwrite(Stringstr)把字符串中的全部字符写入到输出流voidwrite(Stringstr,intoff,intlen)从字符串str中起始于偏移量off处写len个字符到输出流只要不关闭流,每次调用writer()方法就顺序地向文件写入内容,直到流被关闭例9-4首先用字符输出流向一个已经存在的文件尾加若干个字符,然后再用字符输入流读出文件中的内容。,2020/5/27,13,9.4缓冲流(教材印刷错误9.5),1BufferedReader类BufferedReader类创建的对象称为缓冲输入流,该输入流的指向必须是一个Reader流,称为BufferedReader流的底层流,底层流负责将数据读入缓冲区。BufferedReader流的源就是这个缓冲区,缓冲输入流再从缓冲区中读取数据。可以将BufferedReader与FileReader连接,然后BufferedReader就可以按行读FileReader指向的文件。BufferedReader的构造方法如下:BufferedReader(Readerin)BufferedReader流能够读取文本行,方法是readLine()可以向BufferedReader传递一个Reader对象(如FileReader的实例)来创建一个BufferedReader对象:FileReaderinOne=newFileReader(Student.txt)BufferedReaderinTwo=newBufferedReader(inOne);然后inTwo调用readLine()顺序读取文件“Student.txt”的一行。,2020/5/27,14,2BufferedWriter类,可以将BufferedWriter流和FileWriter流连接在一起,然后使用BufferedWriter流将数据写到目的地。FileWriter流称为BufferedWriter的底层流,BufferedWriter流将数据写入缓冲区,底层流负责将数据写到最终的目的地。例如,FileWritertofile=newFileWriter(hello.txt);BufferedWriterout=newBufferedWriter(tofile);BufferedReader流调用方法:write(Stringstr)write(Strings,intoff,intlen)把字符串s或s的一部分写入到目的地。BufferedWriter调用newLine()方法,可以向文件写入一个回行,调用flush()可以刷新缓冲区。例9-5将文件“Student.txt”中的内容按行读出,并写入到另一个文件中,且给每一行加上行号,2020/5/27,15,3标准化考试,标准化试题文件的格式要求如下:每道题目之间用一个或多个星号(*)字符分隔(最后一个题目的最后一行也是*)。每道题目提供A、B、C、D四个选择(单项选择)。test.txt是一套标准化考试的试题文件。例9-6使用输入流读取试题文件,每次显示试题文件中的一道题目。当读取到字符*时,暂停读取,等待用户从键盘输入答案。用户做完全部题目后,程序给出用户的得分。程序运行效果如图9.3。,2020/5/27,16,9.5数组流(教材印刷错误9.6),流的源和目标除了可以是文件外,还可以是计算机内存。ByteArrayInputStream和字节输出流ByteArrayOutputStream分别使用字节数组作为流的源和目标。数组字节输入流ByteArrayInputStream构造方法如下ByteArrayInputStream(bytebuf)ByteArrayInputStream(bytebuf,intoffset,intlength)数组字节输入流调用publicintread()顺序地从源中读出一个字节,该方法返回读出的字节值publicintread(byteb,intoff,intlen)顺序地从源中读出参数len指定的字节数,并将读出的字节存放到参数b指定的数组中,参数off指定数组b存放读出字节的起始位置,该方法返回实际读出的字节个数。如果未读出字节read方法返回-1。数组字节输出流ByteArrayOutputStream的构造方法如下:ByteArrayOutputStream()ByteArrayOutputStream(intsize)字节数组字节输出流调用publicvoidwrite(intb)顺序地向缓冲区写入一个字节publicvoidwrite(byteb,intoff,intlen)将参数b中指定的len个字节顺序地写入缓冲区,参数off指定从b中写出的字节的起始位置publicbytetoByteArray()返回输出流写入到缓冲区的全部字节例9-7向内存(输出流的缓冲区)写入ASCII表,然后再读出这些字节和字节对应的字符。,2020/5/27,17,数组字符流,与数组字节流对应的是数组字符流CharArrayReader和CharArrayWriter类,数组字符流分别使用字符数组作为流的源和目标。与数组字节流不同的是,数组字符流的读操作可能发生IOException异常。例9-8将Unicode表中的一些字符写入内存,然后再读出。,2020/5/27,18,9.6字符串流(教材印刷错误9.7),StringReader使用字符串作为流的源。构造方法:publicStringReader(Strings)构造的输入流指向参数s指定的字符串字符串输入流调用publicintread()顺序读出源中的一个字符,并返回字符在Unicode表中的位置publicintread(charbuf,intoff,intlen)顺序地从源中读出参数len指定的字符个数,并将读出的字符存放到参数b指定的数组中,参数off指定数组b存放读出字符的起始位置,该方法返回实际读出的字符个数。StringWriter将内存作为流的目的地,构造方法:StringWriter()和StringWriter(intsize)可以构造字符串输出流对象字符串输出流调用:publicvoidwrite(intb)向缓冲区写入字符publicvoidwrite(charb,intoff,intlen)向缓冲区写入字符publicvoidwrite(Stringstr)向缓冲区写入字符publicvoidwrite(Stringstr,intoff,intlen)向缓冲区写入字符publicStringtoString()返回输出流写入到缓冲区的全部字符publicvoidflush()可以刷新缓冲区,2020/5/27,19,9.7数据流(教材印刷错误9.8),1DataInputStream类和DataOutputStream类DataInputStream类和DataOutputStream类创建的对象称为数据输入流和数据输出流。它们允许程序按照与机器无关的风格读取Java原始数据。2DataInputStream类和DataOutputStream的构造方法DataInputStream(InputStreamin)创建的数据输入流指向一个由参数in指定的输入流,以便从后者读取数据(按着机器无关的风格读取)。DataOutputStream(OutnputStreamout)创建的数据输出流指向一个由参数out指定的输出流,然后通过这个数据输出流把Java数据类型的数据写到输出流out。表9.1DataInputStream类和DataOutputSteam的部分方法例9-9可以完成写几个Java类型的数据到一个文件,并再读出来。,2020/5/27,20,表9.1DataInputStream类和DataOutputSteam的部分方法,2020/5/27,21,9.8对象流(教材印刷错误9.9),ObjectInputStream类和ObjectOutputStream类创建的对象被称为对象输入流和对象输出流。构造方法:ObjectInputStream(InputStreamin)ObjectOutputStream(OutputStreamout)对象输出流使用writeObject(Objectobj)方法将一个对象obj写入输出流送往目的地,对象输入流使用readObject()从源中读取一个对象到程序中。将一个对象写入到文件时,首先用FileOutputStream创建一个文件输出流,如下所示:FileOutputStreamfile_out=newFileOutputStream(tom.txt);ObjectOutputStreamobject_out=newObjectOutputStream(file_out);准备从文件中读入一个对象到程序中时,首先用FileInputStream创建一个文件输入流,如下所示:FileInputStreamfile_in=newFileInputStream(tom.txt);ObjectInputStreamobject_in=newObjectInputStream(file_in);注:当我们使用对象流写入或读入对象时,要保证对象是序列化的。一个类如果实现了Serializable接口,那么这个类创建的对象就是序列化的对象。使用对象流把一个对象写入到文件时不仅保证该对象是序列化的,而且该对象的成员对象也必须是序列化的。例9-10中有一个实现Serializable接口的Goods类。,2020/5/27,22,9.9序列化与对象克隆(教材印刷错误9.10),有时我们想得到对象的一个“复制品”,该复制品的实体是原对象实体的拷贝。复制品实体的变化不会引起原对象实体发生变化。对象调用clone()方法就可以获取对象的“复制品”,称为原对象的克隆对象。对象进行克隆时需要特别注意的是:如果原对象有引用型成员变量,那么克隆对象对应的成员变量的引用就与原对象那个成员变量的引用相同,克隆对象对自己的这个成员变量所引用的实体的操作,将影响原对象引用型成员变量的实体。这样一来就涉及到深度克隆的问题,因为原对象的成员变量中可能还会有其他对象。因此,程序必须重写clone()方法,增加了编程的难度。使用对象流很容易获取一个序列化对象的克隆。只需将该对象写入到对象输出流,然后用对象输入流读回的对象就是原对象的一个克隆。例9-11将对象写入到内存,然后读回该对象的一个克隆。,2020/5/27,23,9.10随机读写流(教材印刷错误9.11),当用户需要严格地处理文件时,就可以使用RandomAccessFile类来创建一个对象(称为随机读写流)。RandomAccessFile类创建的流的指向既可以作为源,也可以作为目的地。RandomAccessFile类有两个构造方法:RandomAccessFile(Stringname,Stringmode)参数name用来确定一个文件名,给出创建的流的源,也是流目的地。参数mode取r(只读)或rw(可读写),决定创建的流对文件的访问权力。RandomAccessFile(Filefile,Stringmode)参数file是一个File对象,给出创建的流的源,也是流目的地。参数mode取r(只读)或rw(可读写),决定创建的流对文件的访问权力。流还可以调用seek(longa)用来移动RandomAccessFile流的读写位置,其中参数a确定读写位置距离文件开头的字节位置。getFilePointer()获取当前流在文件中的读写的位置。表9.2给出了RandomAccessFile的常用方法。,2020/5/27,24,表9.2RandomAccessFile的常用方法,2020/5/27,25,例题9-12,例题9-12,例9-12把5个int类型整数写入到一个名字为tom.dat文件中,然后按相反顺序读出这些数据。一个int类型数据占4个字节,首先将读写位置移动到文件的第16个字节位置,读取tom.dat文件中最后一个整数,然后将读写位置再移动到文件的第12个字节,读取tom.dat文件中倒数第二个整数,依次类推将tom.dat文件中的整数按相反顺序读出。注:RondomAccessFile流的readLine()方法在读取含有非ASCII字符的文件时(比如含有汉字的文件)会出现乱码问题,因此,需要把readLine()读取的字符串用“iso-8859-1”重新编码存放到byte数组中,然后再用当前机器的默认编码将该数组转化为字符串,操作如下:(1)读取Stringstr=in.readLine();(2)用“iso-8859-1”重新编码byteb=str.getBytes(iso-8859-1);(3)使用当前机器的默认编码将字节数组转化为字符串Stringcontent=newString(b);如果机器的默认编码是“GB2312”,那么Stringcontent=newString(b);等同于:Stringcontent=newString(b,GB2312);例9-13中RondomAccessFile流使用readLine()读取一个文件。,2020/5/27,26,9.11使用Scanner解析文件(教材印刷错误9.12),应用程序可能需要解析文件中的特殊数据,此时,应用程序可以把文件的内容全部读入内存后,再使用第6章的有关知识解析所需要的内容,其优点是处理速度快,但如果读入的内容较大将消耗较多的内存,即以空间换取时间。本节介绍怎样借助Scanner类和正则表达式来解析文件,比如,要解析出文件中的特殊单词,数字等信息。使用Scanner类和正则表达式来解析文件的特点是以时间换取空间,即解析的速度相对较慢,但节省内存。,2020/5/27,27,1使用默认分隔标记解析文件,创建Scanner对象,并指向要解析的文件,例如:Filefile=newFile(hello.java);Scannersc=newScanner(file);那么sc将空格作为分隔标记、调用next()方法依次返回file中的单词,如果file最后一个单词已被next()方法返回,sc调用hasNext()将返回false,否则返回true。对于数字型的单词,比如108,167.92等可以用nextInt()或nextDouble()方法来代替next()方法,即sc可以调用nextInt()或nextDouble()方法将数字型单词转化为int或double数据返回,但需要特别注意的是,如果单词不是数字型单词,调用nextInt()或nextDouble()方法将发生InputMismatchException异常,在处理异常时可以调用next()方法返回该非数字化单词。假设cost.txt的内容如下:TVcost876dollar,Computercost2398dollar.Themilkcost98dollar.Theapplecost198dollar.例9-14中使用Scanner对象解析文件cost.txt中的全部消费并计算出总消费。程序运行效果如图9.4,2020/5/27,28,2使用正则表达式作为分隔标记解析文件,创建Scanner对象,指向要解析的文件,并使用useDelimiter方法指定正则表达式作为分隔标记,例如:Filefile=newFile(hello.java);Scannersc=newScanner(file);sc.useDelimiter(正则表达式);那么sc将正则表达式作为分隔标记,调用next()方法依次返回file中的单词,如果file最后一个单词已被next()方法返回,sc调用hasNext()将返回false,否则返回true。对于数字型的单词,比如1979,0.618等可以用nextInt()或nextDouble()方法来代替next()方法,即sc可以调用nextInt()或nextDouble()方法将数字型单词转化为int或double数据返回,但需要特别注意的是,如
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 钩针套件编织工艺考核试卷及答案
- 催化裂化工工艺考核试卷及答案
- 电机转子噪声检测设备选型工艺考核试卷及答案
- 酸洗钝化工专业技能考核试卷及答案
- 海藻胶提取工技术考核试卷及答案
- 服务心理学(第四版)课件 项目四 任务二 激发消费动机
- 银行转型面试题及答案
- 儿科中级专业试题及答案
- 药学面试专业试题及答案
- 河南省濮阳市华龙区濮阳第一高级中学2025-2026学年高二上学期开学摸底检测生物试卷(含答案)
- 2025年湖南省长沙市开福区财政局招聘历年高频重点提升(共500题)附带答案详解
- DB31∕638-2020 铸钢件单位产品能源消耗限额
- 公安食堂采购合同范例
- 3.1生活在新型民主国家-(教学设计) 2024-2025学年统编版道德与法治九年级上册
- 针刺伤预防与处理-2024中华护理学会团体标准
- 急诊专科护士进修汇报课件
- 高速公路项目竣工决算审计服务投标方案(技术方案)
- 科研项目管理
- 2024-2025学年辽宁省点石联考高三(上)段考数学试卷(10月份)(含答案)
- 基于机器视觉的智能工业物料分拣系统设计研究
- 《计算机制图-中望CAD 2023》中职全套教学课件
评论
0/150
提交评论