电子教案--第9章.ppt_第1页
电子教案--第9章.ppt_第2页
电子教案--第9章.ppt_第3页
电子教案--第9章.ppt_第4页
电子教案--第9章.ppt_第5页
已阅读5页,还剩42页未读 继续免费阅读

下载本文档

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

文档简介

第九章 输入、输出流 n 本章导读 n1. 文件 n2. 文件字节流 n3. 文件字符流 n4. 从键盘读取数据 n5缓冲流 n6数组流 n7字符串流 n8数据流 n9管道流 n10对象流 n11.序列化与对象克隆 n12. 随机读写流 n13. 文件锁 当程序需要读取磁盘上的数据或将程序中得到数 据存储到磁盘时,就可以使用输入输出流,简称I/O流 。I/O流提供一条通道程序,可以使用这条通道读取“ 源”中的数据,或把数据送到“目的地”。I/O流中的 输入流的指向称做源,程序从指向源的输入流中读取 源中的数据;输出流的指向称做目的地,程序通过向 输出流中写入数据把信息传递到目的地。虽然I/O流经 常与磁盘文件存取有关,但是程序的源和目的地也可 以是键盘、鼠标、内存或显示器窗口。 Java的I/O流库提供大量的流类(在包java.io中)。 其中有4个重要的abstract类: n1InputStream(字节输入流) n2Reader(字符输入流) n3OutputStream(字节输出流) n4Writer(字符输出流) 其中InputStream 和Reader类为其子类提供了重要的 读取数据的read方法,OutputStream和Writer类为其 子类提供了重要的写入数据的write方法。我们将陆续 介绍它们的子类及用法。 9.1 文件 Java使用File类创建的对象来获取文件本身的一 些信息,例如文件所在的目录、文件的长度、文件读 写权限等,文件对象并不涉及对文件的读写操作。 创建一个File对象的构造方法有3个: File(String filename); File(String directoryPath,String filename); File(File f, String filename); 其中,filename是文件名字,directoryPath是文件的 路径,f是指定成一个目录的文件。 使用File(String filename)创建文件时,该文件被认 为是与当前应用程序在同一目录中。 1文件的属性 经常使用File类的下列方法获取文件本身的一些信息: public String getName() 获取文件的名字。 public boolean canRead() 判断文件是否是可读的。 public boolean canWrite() 判断文件是否可被写入。 public boolean exits() 判断文件是否存在。 public long length() 获取文件的长度(单位是字节 )。 public String getAbsolutePath() 获取文件的绝对路 径。 public String getParent() 获取文件的父目录。 public boolean isFile() 判断文件是否是一个正常文 件,而不是目录。 public boolean isDirectroy() 判断文件是否是一个 目录。 public boolean isHidden() 判断文件是否是隐藏文件 。 public long lastModified() 获取文件最后修改的时 间(时间是从1970年午夜至文件最后修改时刻的毫秒 数 2目录 (1)创建目录 File对象调用方法:public boolean mkdir()创建一 个目录,如果创建成功返回true,否则返回false(如 果该目录已经存在将返回false)。 (2)列出目录中的文件 如果File对象是一个目录,那么该对象可以调用下 述方法列出该目录下的文件和子目录: public String list() 用字符串形式返回目录下 的全部文件, public File listFiles() 用File对象形式返回 目录下的全部文件。 我们有时需要列出目录下指定类型的文件,比如 .java、.txt等扩展名的文件。可以使用File类的下述 两个方法,列出指定类型的文件, public String list(FilenameFilter obj) 该方 法用字符串形式返回目录下的指定类型的所有文件。 public File listFiles(FilenameFilter obj) 该方法用File对象返回目录下的指定类型所有文件。 FilenameFilter是一个接口,该接口有一个方法: public boolean accept(File dir,String name); 3文件的创建与删除 当使用File类创建一个文件对象后,例如 File f=new File(“c:myletter“,“letter.txt“); 如果c:myletter目录中没有名字为letter.txt文件,文件 对象f调用方法: public boolean createNewFile() 可以在c:myletter目录中建立一个名字为letter.txt的文 件。 文件对象调用方法 public boolean delete() 可以删除当前文件,例如: f. delete(); 在下面的例子1中,列出C:/1000目录下扩展名是 .java文件的名字以及它们的大小,并删除了C:/1000 中的一个.java文件。 4运行可执行文件 当要执行一个本地机上的可执行文件时,可以使用 java.lang包中的Runtime类。首先使用Runtime 类声明一 个对象,如: Runtime ec; 然后使用该类的静态getRuntime()方法创建这个对象: ec=Runtime.getRuntime(); ec可以调用exec(String command)方法打开本地机的可执行 文件或执行一个操作。 下面的例子2中,Runtime对象打开windows平台上的绘图程 序和记事本程序。 返回 9.2 文件字节流 1FileInputStream类 FileInputStream类是InputStream的子类,称为文件字节 输入流。文件字节输入流按字节读取文件中的数据。该类 的所有方法都是从InputStream类继承来的。为了创建 FileInputStream类的对象,可以使用下列构造方法: FileInputStream(String name) FileInputStream(File file) 第一个构造方法使用给定的文件名name创建一个 FileInputStream对象。第二个构造器使用File对象创建 FileInputStream对象。构造方法参数指定的文件称作输 入流的源,输入流通过使用read()方法从输入流读出源中 的数据。 当您使用文件输入流构造器建立通往文件的输入流时,可能 会出现错误(也被称为异常)。例如,当您试图要打开的文 件不存在,就出现I/O错误,Java生成一个出错信号,它使用 一个IOException对象来表示这个出错信号。程序必须使用一 个try-catch块检测并处理这个异常。 输入流的唯一目的是提供通往数据的通道,程序可以通过这 个通道读取数据,read方法给程序提供一个从输入流中读取 数据的基本方法。 read方法的格式如下: int read(); read方法从输入流中顺序读取单个字节的数据。该方法返回 字节值(0255之间的一个整数),读取位置到达文件末尾, 则返回-1。 read方法还有其它一些形式。这些形式能使程序把多 个字节读到一个字节数组中: int read(byte b ); int read(byte b , int off, int len); 其中,off参数指定read方法把数据存放在字节数组b中的 什么地方样,len参数指定该方法将读取的最大字节数。 上面所示的这两个read方法都返回实际读取的字节个数, 如果它们到达输入流的末尾,则返回-1。 FileInputStream流顺序地读取文件,只要不关闭流,每 次调用read方法就顺序地读取文件中其余的内容,直到文 件的末尾或流被关闭。 2FileOutputStream类 与FileInputStream类相对应的类是FileOutputStream类 。FileOutputStream提供了基本的文件写入能力。 FileOutputStream类是OutputStream的子类,称为文件 字节输出流。文件字节输出流按字节将数据写入到文件 中。为了创建FileOutputStream类的对象,可以使用下 列构造方法: FileOutputStream(String name) FileOutputStream(File file) 第一个构造方法使用给定的文件名name创建一个 FileOutputStream对象。第二个构造方法使用File对象 创建FileOutputStream对象。构造方法参数指定的文件 称作输出流的目的地,输出流通过使用write()方法把数 据写入输出流到达目的地。 FileOutputStream对象可以使用write方法把字节发送 给输出流,write的用法如下: public void write(byte b) 写b.length个字节到输出 流。 public void.write(byte b,int off,int len) 从给定 字节数组中起始于偏移量off处写len个字节到输出流,参数 b是存放了数据的字节数组。 FileOutStream流顺序地写文件,只要不关闭流,每次调用 writer方法就顺序地向文件写入内容,直到流被关闭。如果 输出流要写入数据的文件已经存在,该文件中的数据内容就 会被刷新;如果要写入数据的文件不存在,该文件就会被建 立。 在下面的例子3中,首先将“欢迎Welcome”写入到 “hello.txt”中,然后再读取该文件中的内容。 返回 9.3 文件字符流 1FileReader类 为了创建FileReader类的对象,可以使用下列构造方 法: FileReader(String name) FileReader (File file) 第一个构造方法使用给定的文件名name创建一个 FileReader 对象。第二个构造方法使用File对象创建 FileReader对象。构造方法参数指定的文件称作输入 流的源,输入流通过使用read()方法从输入流读出源 中的数据。以下是read方法的功能解释: int read() 输入流调用该方法从源中读取一个字符 ,该方法返回一个整数(065535之间的一个整数, Unicode字符值),如果未读出字符就返回-1。 int read(char b ) 输入流调用该方法从源中读取 b.length个字符到字符数组b中,返回实际读取的字符 数目。如果到达文件的末尾,则返回-1。 int read(char b , int off, int len) 输入流调 用该方法从源中读取len个字符并存放到字符数组b中 ,返回实际读取的字符数目。如果到达文件的末尾, 则返回-1。其中,off参数指定read方法从符数组b中 的什么地方存放数据 2FileWriter类 FileWriter提供了基本的文件写入能力。FileWriter 类是Writer的子类,称为文件字符输出流。文件字符 输出流按字符将数据写入到文件中。为了创建 FileWriter类的对象,可以使用下列构造方法: FileWriter(String name) FileWriter (File file) 第一个构造方法使用给定的文件名name创建一个 FileWriter对象。第二个构造方法使用File对象创建 FileWriter对象。构造方法参数指定的文件称作输出 流的目的地,输出流通过使用write()方法把字符数据 写入输出流到达目的地。 FileWriter对象可以使用write方法把字符数据写入输 出流,write的用法如下: public void write(char b) 写b.length个字符到 输出流。 public void.write(char b,int off,int len) 从 给定字符数组中起始于偏移量off处写len个字符到输 出流,参数b是存放了数据的字符数组。 void write(String str) 把字符串中的全部字符写 入到输出流。 void write(String str,int off,int len) 从字符 串str中起始于偏移量off处写len个字符到输出流。 在下面的例子4中,首先用字符输出流向一个文件写入 若干个字符,然后再用字符输入流读出文件中的内容 。 返回 9.4 从键盘读取数据 java.lang包中的System类有两个重要的类成员:in和 out,分别是输入流和输出流类型的对象。 in的源是 键盘,in可以读取用户从键盘键入的数据。 Scanner是JDK1.5新增的一个类,该类可以使用in初始 化一个对象: Scanner reader=new Scanner(System.in); 然后reader对象调用方法,读取用户在命令行输入的 各种数据类型。 out流的目的地是命令行窗口,out调用方法可以将数 据送到命令行窗口。 有关in和out的讲解可参见第2章,4节。 返回 9.5 缓冲流 1BufferedReader类 BufferedReader类创建的对象称为缓冲输入流,该 输入流的指向必须是一个Reader流,称作 BufferedReader流的底层流,底层流负责将数据读入 缓冲区,BufferedReader流的源就是这个缓冲区,缓 冲输入流再从缓冲区中读取数据。 BufferedReader的构造方法是: BufferedReader(Reader in) BufferedReader流能够读取文本行,方法是 readLine()。 通过向BufferedReader传递一个Reader对象(如 FileReader的实例),来创建一个BufferedReader对 象,如: FileReader inOne=new FileReader(“Student.txt“) BufferedReader inTwo=new BufferedReader(inOne); 然后inTwo调用readLine()顺序读取文件 “Student.txt”的一行。 2BufferedWriter类 类似地,可以将BufferedWriter流和FileWriter流连接在 一起,然后使用BufferedWriter流将数据写到目的地, FileWriter流称作BufferedWriter的底层流, BufferedWriter流将数据写入缓冲区,底层流负责将数据 写到最终的目的地。例如: FileWriter tofile=new FileWriter(“hello.txt“); BufferedWriter out=new BufferedWriter(tofile); BufferedReader流调用方法: write(String str) write(String s,int off,int len) 把字符串s或s的一部分写入到目的地。 在下面的例子5中,我们将文件“Student.txt”中的内容 按行读出,并写入到另一个文件中,且给每一行加上 行号。 返回 9.6 数组流 字节输入流:ByteArrayInputStream 和字节输出 流:ByteArrayOutputStream分别使用字节数组作为流 的源和目标。使用下列ByteArrayInputStream流的两 个构造方法构造字节数组输入流对象: ByteArrayInputStream(byte buf) ByteArrayInputStream(byte buf,int offset,int length) 第一个构造方法构造的数组字节流的源是参数buf指定 的数组的全部字节单元,第二个构造方法构造的数组 字节流的源是参数buf指定的数组从offset处取的 length个字节单元。 使用下列ByteArrayOutputStream流的两个构造方 法构造字节数组输出流对象: ByteArrayOutputStream () ByteArrayOutputStream(int size) 第一个构造方法构造的数组字节输出流指向一个默认 大小为32字节的缓冲区,如果输出流向缓冲区写入的 字节个数大于缓冲区时,缓冲区的容量会自动增加。 第二个构造方法构造的数组字节输出流指向的缓冲区 的初始大小由参数size指定,如果输出流向缓冲区写 入的字节个数大于缓冲区时,缓冲区的容量会自动增 加。 数组字节输出流调用 public byte toByteArray() 方法,可以返回输出流写入到缓冲区的全部字节。 数组字节流读写操作不会发生IOException异常。 在下面的例子6中,我们向内存(输出流的缓冲区)写 入ASCII表,然后再读出这些字节和字节对应的字符。 与数组字节流对应的是数组字符流: CharArrayReader与CharArrayWriter类,数组字符流 分别使用字符数组作为流的源和目标。与数组字节流 不同的是,数组字符流的读操作可能发生IOException 异常。 在下面的例子7中,我们将Unicode表中的一些字符写 入内存,然后再读出。 返回 9.7 字符串流 StringReader使用字符串作为流的源。使用下列 构造方法构造字符串输入流对象: public StringReader(String s) 该构造方法构造的输入流指向参数s指定的字符串,字 符串输入流调用 public int read() 方法顺序读出源中的一个字符,并返回字符在Unicode 表中的位置;调用 public int read(char buf,int off,int len) 方法可以顺序地从源中读出参数len指定的字符个数, 并将读出的字符存放到参数b指定的数组中,参数off 指定数组b存放读出字符的起始位置,该方法返回实际 读出的字符个数。 字符串输出流调用下列方法可以向缓冲区写入字符: public void write(int b) public void write(char b,int off,int len) public void write(String str) public void write(String str,int off,int len) 字符串输出流调用 public String toString() 方法,可以返回输出流写入到缓冲区的全部字符;调用 public void flush() 方法可以刷新缓冲区。 返回 9.8 数据流 1DataInputStream类和DataOutputStream类 DataInputStream 类和DataOutputStream类创建的对象称 为数据输入流和数据输出流。这两个流是很有用的两个流 ,它们允许程序按着与机器无关的风格读取Java原始数据 。也就是说,当我们读取一个数值时,不必再关心这个数 值应当是多少个字节。 2DataInputStream类和DataOutputStream的构造方法 (1)DataInputStream(InputStream in) 将创建的数据 输入流指向一个由参数in指定的输入流,以便从后者读取 数据(按着机器无关的风格读取)。 (2)DataOutputStream(OutnputStream out) 将创建的 数据输出流指向一个由参数out指定的输出流,然后通过 这个数据输出流把Java数据类型的数据写到输出流out。 表9.1(见书208页)给出了DataInputStream类和 DataOutputStream类的常用方法。 下面的这个例子8应用程序可以完成写几个Java类型的 数据到一个文件,并再读出来。 返回 9.9 管道流 管道是不同线程之间直接传输数据的基本手段。 一个线程A通过它的输出管道发送数据,另一个线程B 从自己的输入管道中读取数据,因为B把自己的输入管 道接到了A的输出管道上了。 可以使用PipedInputStream类的无参数构造方法创建 一个管道输入对象: PipedInputStream in=new PipedInputStream(); 管道输入流in 处于等待连接状态,要使用in,必须再使 用PipedOutputStream类的构造方法创建一个等待连接的 管道输出流: PipedOutputStream out=new PipedOutputStream(); 然后使用connect(PipedOutputStream c)方法把in和out 相连接: in.connect(out); 也可以使用带参数的构造方法: PipedInputStream(PipedOutputStream a) 创建一个管道输入流,它被连接到由参数a指定的管道输 出流。 可以使用PipedOutputStream 类的无参数构造方 法创建一个管道输出流: PipedOutputStream out=new PipedOutputStream (); 管道输出流out 处于等待连接状态,要使用out,必须 再使用PipedInputStream类的构造方法创建一个等待 连接的管道输入流: PipedInputStream in=new PipedInputStream (); 然后使用connect(PipedInputStream c)方法把in和 out相连接: out.connect(in); 也可以使用带参数的构造方法 PipedOutputStream(PipedInputStream a) 创建一个管道输出流,它被连接到由参数a指定的管道 输入流。 在下面的例子9模拟两个人玩猜数字游戏。第一个 线程首先向第二个线程发出一句话:“给你一个1至 100之间的数,请您猜”,然后就等待第二个线程的回 复。第二个线程将自己的猜测发给第一个线程,第一 个线程收到回复后,将根据收到的猜测的情况,再向 第二个线程发出:“您猜大了”、“您猜小了”或“ 您猜对了”这样的信息。第二个线程再根据收到的信 息继续将自己的猜测发给第一个线程。 返回 9.10 对象流 1ObjectInputStream类和ObjectOutputStream类 ObjectInputStream类和ObjectOutputStream类分别是 InputStream类和OutputStream类的子类。 ObjectInputStream类和ObjectOutputStream类创建的 对象被称为对象输入流和对象输出流。对象输出流使 用writeObject(Object obj)方法将一个对象obj写入 输出流送往目的地,对象输入流使用readObject()从 源中读取一个对象到程序中。 ObjectInputStream类和ObjectOutputStream类的构造 方法分别是: ObjectInputStream(InputStream in), ObjectOutputStream(OutputStream out)。 当我们使用对象流写入或读入对象时,要保证对象是 序列化的。这是为了保证能把对象写入到文件,并能再 把对象正确读回到程序中的缘故。Java提供给我们的绝 大多数对象都是所谓序列化的,比如组件等。一个类如 果实现了Serializable接口,那么这个类创建的对象就 是所谓序列化的对象。Serializable接口中的方法对程 序是不可见的,因此实现该接口的类不需要实现额外的 方法,当把一个序列化的对象写入到对象输出流时,JVM 就会实现Serializable接口中的方法,按着一定格式的 文本将对象写入到目的地。需要注意的是:使用对象流 把一个对象写入到文件时不仅要保证该对象是序列化的 ,而且该对象的成员对象也必须是序列化的。 在下面的例子10中有一个实现接口Serializable的Goods 类。 返回 9.11 序列化与对象克隆 对象调用clone方法就可以获取对象的“复制品”, 称作原对象的克隆对象。 对象进行克隆时需要特别注意的是:如果原对象有引 用型成员变量,那么克隆对象对应的成员变量的引用就与 原对象那个成员变量的引用相同,那么,克隆对象对自己 的这个成员变量所引用的实体的操作,将影响原对象引用 型成员变量的实体。这样一来就涉及到一个深度克隆问题 ,因为,原对象的成员变量中可能还会有其它对象。因此 ,程序必须重写clone方法,增加了编程的难度。 使用对象流很容易得获取一个序列化对象的克隆。我们只 需将该对象写入到对

温馨提示

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

评论

0/150

提交评论