JavaIO讲义.docx_第1页
JavaIO讲义.docx_第2页
JavaIO讲义.docx_第3页
JavaIO讲义.docx_第4页
JavaIO讲义.docx_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

1. 文件操作类FileFile类是Java文件处理的最基本的类,它用于实现对目录的创建、删除,对文件的创建、重命名、删除。因此,File类操作的对象分为两类:目录和文件根据File类的操作功能,可以进行如下的各种操作1.1 创建File实例在能够操作目录或文件之前,要先创建一个对象,指向目录或文件。File有4个构造函数来创建一文件对象。*File(String pathname):通过将给定路径名字符串转换为抽象路径名来创建一个新File实例File path = new File(D:/demo);/目录对象File file = new File(D:/demo/test.txt); /文件对象*File(String parent,String child):根据parent路径名字符串和child路径名字符串创建一个新File实例File file = new File(D:/demo,test.txt);*File(URI uri):通过将给定的file:URI转换为一个抽象路径名来创建一个新的File实例。File file = new File(file:/D:/demo/test.txt);*File(File parent,String child):根据parent抽象路径名和child路径名字符串创建一个新File实例File file = new File(path,test.txt);其中,第一个函数直接根据目录或文件的全路径名来创建,第二个函数则将路径和文件名分开输入,第三个函数用来指向一个URL,最后一个函数则根据目录实例来创建文件。1.2 判断是目录还是文件对于上面创建的File实例,由于都是通过路径字符串来创建的,所有并不知道它是目录还是文件。此时可以通过下面的函数来判断*isDirectory():是否是目录*isFile():是否是文件1.3 检查目录或文件是否存在*exists()1.4 创建目录或文件*mkdir():创建一个目录*mkdirs():创建所有目录*createNewFile():创建一个文件1.5 查看目录下的文件列表。并输出路径名对于目录来说,可以使用listFiles()取得该目录下的文件列表,它返回的是一个File类型的数组。我们可以循环该数组取得每一个文件对象,并可以使用getAbsolutePath()获取该对象的路径名。File p = new File(D:/work);File fileList = p.listFiles();for(File f:fileList)System.out.println(f.getAbsolutePath();从输出结果可以看出,这里既有目录,又有文件。因此,通过listFiles()取得的文件列表中,即包含目录又包含文件。1.6 重命名文件名对于文件,我们可以使用renameTo()函数重命名一个新的文件名,参数为一个新的File实例。File file = new File(D:/work/demo/test.txt);File f = new File(D:/work/demo/test2.txt);if(file.isFile()file.renameTo(f);2. 文件搜索类FileFilter与FilenameFilter如何快速地按照特定要求找出所有文件呢?此时可以使用两个文件搜索类FileFilter与FilenameFilter,它们都是接口,只需要我们编写自己的实例类来实现它们的函数accept()即可。FileFilter的主要作用就是检测文件是否存在,FileFilter和它的前身FilenameFilter唯一的不同是,FileFilter提供文件对象的访问方法,而FilenameFilter是按照目录和文件名的方式来工作的。FileFilter拥有下面的一个过滤函数接口,用户的实现类只需要实现函数,对不同的文件进行过滤即可:boolean accept(File file);而FilenameFilter的过滤函数时按照目录和文件名来进行的:boolean accept(File directory,String name);下面我们通过实例来讲解这两个类的使用。2.1 FileFilter的使用一个简单的例子是搜索特定的文件扩展名。你可以使用FilenameFilter,但是出来的结果会让你很难判断到底是目录还是文件。要解决这个问题,你需要使用FileFilter对象。下面通过实例来演示它的使用。首先定义一个扩展名过滤器类ExtensionFilter,它实现了接口FileFilter。添加一个变量Extension,表示待匹配的文件扩展名,并在构造函数中初始化该变量。接下来是最重要的接口函数accept(),这是实现按照扩展名过滤的地方。public class ExtensionFilter implements FileFilter private String str;public ExtensionFilter(String str)this.str=str;Overridepublic boolean accept(File pathname) if(pathname.isDirectory()return false;String fileName = pathname.getName();int index = fileName.indexOf(.);if(index=-1)return false;else if(index=fileName.length()-1)return false;elsereturn this.str.equals(fileName.substring(index+1);public static void main(String args) File file = new File(D:/work/demo);ExtensionFilter ef=new ExtensionFilter(txt);File fileList = file.listFiles(ef);for(File f:fileList)System.out.println(f.getAbsolutePath();运行测试类结果如下:D:workdemo1.txtD:workdemo3.txtD:workdemotest.txt2.2 FilenameFilter的使用Filename的过滤函数accept()则直接根据目录和文件名进行过滤,与FileFilter相比,多了一个文件名参数。下面我们通过开发一个图片过滤器ImageFilter来演示它的使用,我们的目标是过滤扩展名为.gif,.jpg,.png的文件,实现的完整代码如下。public class ImageFilter implements FilenameFilterpublic boolean accept(File dir, String name) return isGif(name)|isJpg(name)|isPng(name);private boolean isGif(String filename)if(filename.toLowerCase().endsWith(.gif) return true;else return false;private boolean isJpg(String filename)if(filename.toLowerCase().endsWith(.jpg) return true;else return false;private boolean isPng(String filename)if(filename.toLowerCase().endsWith(.png) return true;else return false;public static void main(String args) File file = new File(D:/work/workNote/考勤截图/2014/8月);ImageFilter iFilter =new ImageFilter();File fileList = file.listFiles();for(File f:fileList)System.out.println(f.getAbsolutePath();输出如下:D:workworkNote考勤截图20148月2014年8月11日.pngD:workworkNote考勤截图20148月2014年8月12日.pngD:workworkNote考勤截图20148月2014年8月13日a.pngD:workworkNote考勤截图20148月2014年8月13日b.pngD:workworkNote考勤截图20148月2014年8月18日.pngD:workworkNote考勤截图20148月2014年8月19日.pngD:workworkNote考勤截图20148月2014年8月1日.pngD:workworkNote考勤截图20148月2014年8月20日.pngD:workworkNote考勤截图20148月2014年8月21日.png3 文件随机读写类RandomAccessFile刚才讲解的File类,以及FileFilter和FilenameFilter类,都是对文件和目录进行操作,不能够实现对文件内容的读写。要实现对文件内容的随机读写,可以使用RandomAccessFile类。RandomAccessFile类能够随机访问文件,它将文件内容存储在一个大型byte数组中。它存在着指向该隐含byte数组的光标或索引,称为文件指针,该指针位置可以通过seek方法设置。输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含byte数组的当前末尾之后的输出操作导致该数组扩展。通常,如果此类中的所有读取例程在读取所需数量的字段之前已到达文件末尾,则抛出EOFExtension(是一种IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件未尾,则抛出IOException,而不是EOFException。需要特别指出的是,如果流已被关闭,则可能抛出IOException。下面我们来看看如何通过RandomAccessFile来随机读写文件。下面我们从打开关闭文件、读取文件和写入文件3个方面讲解RandomAccessFile的使用。3.1 打开与关闭文件创建随机访问文件的实例,可以使用如下的两种构造函数*RandomAccessFile(File file,String mode):创建从中读取和向其中写入(可选)的随机访问文件流,该文件由File参数指定。*RandomAccessFile(Stirng name,String mode):创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。第一种是通过一个File对象创建,第二种则直接指定文件名。其中的参数mode表示对目标文件的访问模式,可选值如表9-1下例演示了采用读写模式打开文件D:/demo/test.txt的方法:RandomAccessFile file = new RandomAccessFile(D:/demo/test.txt,rw);然后在完成了对文件的一系列操作之后,还需要使用close()函数关闭文件:file.close();打开文件后,还可以在文件的长度范围内设置指针位置。(1)读取文件长度可以使用length()取得文件的长度,该数值是该文件的字节数,如下例所示:long size = file.length();System.out.println(文件大小:+size);(2)设置文件指针位置打开文件后,默认的读取指针指向文件的最开始处,即0。RandomAccessFile类之所以是随机访问类,就是因为它能够自动定位读取的指针。此时可以使用seek(long pos)方法来定位读取位置,如下例所示:file.seek(4);3.2 读取文件打开文件后,即可从该文件中读取数据。RandomAccessFile类提供了以下几种操作。3.2.1 读取一个数据字节:read()read()函数从该文件的当前指针位置读取一个字节,可以将该字节转化为字符输出,如下例所示:int c = file.read();System.out.println(char)c);每调用一次read()函数,读取的指针就会往后移到一个字节的位置。3.2.2 读取字节数组:read(byte b);该函数能够一次性读取多个字节,读取的长度为字节数组b的长度,如下例所示:byteb = new byte3;file.read(b);String str = new String();System.out.println(str);3.2.3 灵活读取字节数组:read(byteb,int off,int len)上面的函数填充了数组的所有长度,还可以使用参数off指定填充数组的起始位置,并使用len指定从文件中读入的字节长度,如下例所示:byteb2 = new byte3;file.read(b2,1,2);3.2.4 读取固定类型的数值还可以使用下面的函数来读取固定类型的数值:boolean readBoolen();/读取一个booleanbyte readByte();/读取一个有符号的8位值char readChar();/读取一个字符double readDouble();/读取一个doublefloat readFloat();/读取一个floatint readInt();/读取一个有符号的32位整数long readLong();/读取一个有符号的64位整数short readShort();/读取一个有符号的8位数int readUnsignedByte();/读取一个无符号的8位数int readUnsignedShort();/读取一个无符号的16位数3.2.5 读取一行字符串:readLine();上面的读取函数都是读入的byte类型的字节,也就是按位读取的,通常我们会需要读取文件的一行,此时可以使用readLine(),它返回String类型的字符串。System.out.println(file.readLine);(6)读取中文字符:readUTF();对于上面的所有函数,都是按照字节码读取的,如果有中文出现,readLine()会显示乱码。此时可以使用readUTF()来读取。它从当前文件指针开始读取前两个字节,类型于使用readunsignedShort.此值给出已编码字符串中随后的字节数,而不是结果字符串的长度。随后的字节解释为UTF-8修改版格式的字节编码字符,并转换为字符。System.out.println(file.readUTF();3.3 写入文件3.3.1 写入一个数据字节:write();write()函数在该文件的当前指针位置写入一个字节,并覆盖原有的字节。file.write(100);每调用一次write()函数,读取的指针就会往后移到一个字节的位置。3.3.2 写入字节数组:write(byteb)该函数能够一次性写入多个字节,写入的长度为字节数组b的长度。bytebw = new byte3;/创建字节数组bw0 = 100;/写入字符d的ASCII码bw1 = 101;/写入字符e的ASCII码bw2 = 102;/写入字符f的ASCII码file.write(bw);/写入字节数组执行后,就会在指针位置写入“def”3个字符。3.3.3 灵活写入字节数组:read(byteb,int off,int len)上面的函数写入了数组的所有长度,还可以使用参数off指定写入数组的起始位置,并使用len指定数组中写入了数组的所有长度,还可以使用参数off指定写入数组的起始位置,并使用len指定从数组中写入的字节长度。file.write(bw,1,2);/写入从1开始,长度为2的数组,即ef3.3.4 写入固定类型的数值还可以使用下面的函数来写入固定类型的数值:writeBoolean(boolean v);/按单字节值将boolean写入该文件writeByte(int v);/按单字节值将byte写入该文件writeByte(String s);/按字节系列将该字符串写入该文件writeChar(int v);/按双字节值将char写入该文件,先写高字节writeChars(String s);/按字符序列将一个字符串写入该文件writeDouble(double v);/使用Double类中的doubleToLongBits方法将双精度参数转换为一个long,r然后按8字节数量将该long值写入该文件,先写高字节writeFloat(float v);/使用Float类中的floatToIntBits方法将浮点参数转换为一个int,然后按4字节数量将该int值写入该文件,先写高字节writeInt(int v); /按4个字节将int写入该文件,先写高字节writeLong(long v);/按8个字节将long写入该文件,先写高字节writeShort(int v);/按2个字节将short写人该文件,先写高字节3.3.5 写入一个字符串:writeBytes()与writeChars()还可以使用writeChars()写入一个字符串,与writeBytes()不同的是,writeChars()写入的每一个字符都是按照双字节写入的,即一个字符占用2个字节。file.wrtieBytes(AA);还可以使用writeChars()写入一个字符串,与writeBytes()不同的是,writeChars()写入的每一个字符都是按照双字节写入的,即一个字符占用2个字节。file.writeChars(DD);这实际上是写入了“DD”4个字节,高位以0填充。3.3.6 写入中文字符;writeUTF()对于上面的所有函数,都是按照字节码写入的,如果有中文出现,writeBytes()和writeChars()会显示乱码。首先,它把2个字节从文件的当前文件指针写入到此文件,类似于使用writeShort方法并给定要跟随的字节数。此值是实际写入的字节数,而不是该字符串的长度。在该长度之后,按顺序输出该字符的每个字符,并对每一个字符使用UTF-8修改版编码。file.writeUTF(中国);/写入中文字符4. 输入/输出流Java IO是最关键的4个父类是:InputStream(输入字节流)、OutputStream(输出字节流)、Reader(输入字符流)、Writer(输出字符流)。它们都是public abstract class类。上述4个父类可以分为三大类:*第一类:数据源类*第二类:数据流串联类*第三类:数据流过滤类其中的数据源类是创建各种流的起始类,第二类和第三类都是各自流实例的包装。在该表中,斜体的部分表示的是抽象类(不能够被实例化;必须通过子类创建实例)。粗体的部分是应用中比较常用的类,应该重点关注。输入字节流输出字节流输入字节流输出字节流抽象类InputStreamOutputStreamReaderWriter转换类InputStreamReaderOutputStreamWriter第一类:数据源数组ByteArrayInputStreamByteArrayOutputStreamCharArrayReaderCharArrayWriter文件FileInputStreamFileOutputStreamFileReaderFileWriter对象ObjectInputStreamObjectInputStream字符串StringBufferInputStreamStringReaderStringWriter第二类:数据流串联类管道PipeInputStreamPipeOutputStreamPipeReaderPipeWriter序列SequenceInputStrean第三类:数据流过滤类过滤FilterInputStreamFilterOutputStreamFilterReaderFilterWriter缓存BufferedInputStreamBufferedOutputStreamBufferedReaderBufferedWriter数据DateInputStreamDateOutputStream行号LineNumberInputStreamLineNumberReader推回PushbackInputStreamPushbackReader格式化PrintStreamPrintWriter4.1 流的运作原理无论是哪种编程语言,输入与输出都是十分重要的一部分,Java也不例外,而且Java将输入/输出的功能和使用范畴做了很大的扩充。它采用了流的机制来实现输入/输出。所谓流,就是数据的有序排序,而流可以是从某个源(称为流源)出来,到某个目的地去的。*根据流的方向的不同,可以分成输入流和输出流,一个程序从输入流读取数据向输出流写数据。*根据流的数据类型不同,有可以分为字节流和字符流,字节流可以实现向字符流的转换。输入流和输出流是两个相反的流,一个负责读取数据,一个负责输出数据。而输入流和输出流还可以通过各种流的过滤器进行包装,形成流的链,以拥有更多的功能。下面我们先来讲解这4个概念的运作原理。4.1.1 输入流举个例子来说,如果一个程序可以用FileInputStream类从一个磁盘文件读取数据,这就是输入流,如图9-1所示。像FileInputStream这样的处理器叫做流处理器,它就像流的管道一样,从一个流源吸入某个类型的数据,并输出某种类的数据。4.1.2 输出流同样道理,也可以用输出流FileOutputStream类向一个磁盘文件写数据,如图9-2所示。在实际应用中,程序需要写出的通常是非常结构化的信息,因此这些byte类型的数据实际上是一些数值、文字、源代码等。4.1.3 输入流链Java的I/O库提供一个称做链接(Chaining)的机制,可以将一个流处理器跟另一个流处理器首尾相接,以其中之一的输出作为另一个的输入,形成一个流管道的链接。例如,DataInputStream流处理器可以把FileInputStream流对象的输出当做输入,将byte类型的数据转换成Java的原始类型和String类型的数据,如图9-3所示。4.1.4 输出流链向一个文件写入byte类型的数据不是一个简单的过程。一个程序需要向一个文件里写入的数据往往都是结构化的,而byte类型则是原始类型。因此在写的时候必须经过转换。DataOutputStream流处理器提供了接收原始数据类型和String数据类型,而这个流处理器的输出数据则是byte类型。也就是说DateOutputStream可以将源数据转换成Byte类型的数据,再输出。这样一来,就可以将DataOutputStream与FileOutputStream链接起来,这样程序就可以将原始数据类型和String类型的源数据写入这个链接好的双重管道里面,达到将结构化数据写到磁盘文件里面的目的,如图9-4所示。流处理器所处理的流必定都有流的输入源,而如果将流类所处理的流源分类的话,基本可以分为两大类。*第一类:数组、String、File等,这一种叫原始流源。*第二类:同样类型的流用做链接流类的流源,叫链接流源。接下来的4个小节中,我们将分别讲解输入字节流、输出字节流、输入字符流和输出字符流,在讲解每一种流时,都按照以上的两种情况分类讲解。4.2 输入字节流InputStreamInputStream的作用是标志那些从不同输入源产生输入的类。InputStream是所有输入字符流的抽象父类,因此不能够直接构造InputStream的实例,必须通过它的子类来进行构造。由于它是抽象类,因此提供了一些抽象接口和固有的函数实现,如下所示:abstract int read();/从输入流读取数据的下一个字节int read(byte b);/从输入流中读取字节数组,并将其存储在缓存区数组b中int read(byte b,int off,int len);/将输入流中最多len个数据字节读入byte数组int available();/返回此输入流可以读取(或跳过)的估计字节数long skip(long n);/跳过河丢弃此输入流中数据的n个字节void close();/关闭此输入流并释放与该流关联的所有系统资源第一个函数是读取一个字节的函数,由于每一种实现类的实现机制不同,因此,这个函数必须在实现类中实现。其他的读取函数则调用了该函数进行读取,对每一种实现类都相同,因此在这里看出,继承InputStream抽象类的实现类只需要重写read()函数就可以了。java.io的包中为我们提供了InputStream的一系列实现,各子类如果9-5所示。根据输入源的不同,共分为如下几种类型。*ByteArrayInputStream:把内存中的一个缓存区作为InputStream使用。*FIleInputStream:把一个文件作为InputStream,实现对文件的读取操作。*ObjectInputStream:把一个对象作为InputStream,实现对对象的读取操作。*StringBufferInputStream:把一个String对象作为InputStream.并且它还有3个特殊的实现。*PipedInputStream:实现了管道(pipe)的概念,主要在线程中使用。*SequenceInputStream:把多个InputStream合并为一个InputStream。*FilterInputStream:对输入流进行各种过滤操作。FilterInputStream还有一组过滤器的具体实现。*BufferedInputStream:缓存过滤器。*DataInputStream:数据过滤器。*LineNumberInputStream:行号过滤器。*PushbackInputStream:回退过滤器。下面我们根据具体使用的不同场景,来讲解分别应该选择使用什么样的输入流的类。4.2.1 字节数组作为输入源-ByteArrayInputStreamByteArrayInputStream包含一个内部缓存区,该缓存区包含从流中读取的字节,并使用内部计数器跟踪read()方法要提供的下一个字节。所谓的内存缓存区,就是对应了内存中存在的字节数组,因此可以根据字节数组来创建该类的实例。它共包括如下二个构造函数:ByteArrayInputStream(byte buf); /使用buf作为缓存区数组ByteArrayInputStream(byte buf,int offset,int length)/使用buf作为缓存区数组该类重写了Inputstream中的所有方法,因此我们可以调用父类inputStream的所有方法来执行读的所有操作。程序9-10演示了通过一个字节数组怎么实现输入流的过程。并从该输入流中读取数据展示在控制台中。public class ByteArrayInputStreamTest public static void main(String args) byte buf = new byte3;buf0=100;buf1=101;buf2=102;try ByteArrayInputStream is =new ByteArrayInputStream(buf);byte b = new byte3;is.read(b);System.out.println(new String(b); catch (IOException e) e.printStackTrace();从该类的使用实例来看,它只是将字节数组转换为另一个字节数组,从表面上看好像并没有什么实际意义。但实际上,它将字节数组转换成了流式读取,这样就可以通过流的方式从内存中读取一个字节,而不需要直接操作数组,这就是转换的好处。同时,它还为字符提供了输入源Tips本节对流操作的代码进行了IOException异常的捕获,凡是涉及到输入流,输出流操作的,都需要进行异常捕获。4.2.2 文件作为输入源-FileInputStreamFileInputStream从文件系统中的某个文件中获得输入字节,适用于读取诸如图像数据之类的原始字节流。它可以通过如下两种方式创建:FileInputStream(File file);/该文件通过文件系统中的File对象file指定FileInputStream(String name);/该文件通过文件系统中的路径名name指定同样的我们也可以通过重写InputStream的名称的名称来读取文件内容。下例程序演示了如果读取一个磁盘的文件来建立一个文件输入流,循环读取该数据流中的数据并输出到控制台。public class FileInputStreamTest public static void main(String args) try FileInputStream is = new FileInputStream(D:/work/demo/test.txt);while(is.available()0)int c = is.read();System.out.print(char)c);is.close(); catch (IOException e) e.printStackTrace();运行以上程序,将会在控制台中输出文件D:/work/demo/test.txt内容。4.2.3 对象作为输入源-ObjectInputStreamObjectInputStream和ObjectOutputStream分别于FileInputStream和FileOutputStream一起用的时,可以为应用程序提供对对象图像持久存储。ObjectInputStream用户恢复之前序列化存储的对象,ObjectInputStream确保从流创建的的图形中所有对象的类型与Java虚拟机中显示的类相匹配。只有支持java.io.Serializable或java.io.Externalizable接口的对象才能从流读取。例如,要从由ObjectOutputStream的实例写入的文件中读取数据,可通过如下代码实现:FileInputStream fis = new FileInputStream(t.tmp);ObjectInputStream ois = new ObjectInputStream(fis);int i =ois.readInt();String today=(String)ois.readObject();Date date=(Date)ois.readObject();ois.close();readObject()方法负责读取通过对应的writeObject()方法写入的数据,为特定类读取和恢复对象的状态。该方法本身的状态,不管属于其超类还是属于其子类,都没有关系。恢复状态的方法时,从个别字段的ObjectInputStream读取数据并将其分配给对象的适当字段。除此之外,与ObjectOutputStream类的写各种数据类型的函数相对应,它还提供了对各种数量类型的读取函数:程序9-12演示了读取ObjectOutputStream类所写文件的过程,读取文件test.tmp可以通过下一节中ObjectOutputStream类的演示程序运行生成。在该程序中,首先需要创建一个FileInputStream实例来创建文件输出流fis,然后再根据fis来创建ObjectInputStream类型的输入流。最后就可以调用各种读取函数读取该文件中的数据了。FileInputStream fis =new FileInputStream(D:/work/demo/test.tmp);ObjectInputStream ois =new ObjectInputStream(fis);int i=ois.readInt();String str=(String)ois.readObject();Date date =(Date)ois.readObject();System.out.println(i+&+str+&+date);ois.close();4.2.4 字符串作为输入源-StringBufferInputStreamStringBufferInputStream允许输入流由字符串内容提供,与ByteArrayInputStream使用字节数组作为输入源相类型。创建该实例的方法只有一个:StringBufferInputStream(String s);/以从指定字符串读取数据只需要使用一个字符串作为输入即可创建。public class StringBufferInputStreamTest public static void main(String args) try StringBufferInputStream is=new StringBufferInputStream(Hello World!);while(is.available()0)int c = is.read();System.out.print(char)c);is.close(); catch (IOException e) e.printStackTrace();Tips由于此类未能正确地将字符转换为字节。从JDK1.1开始,从字符串创建流的首选方法是通过StringReader类进行创建的。4.2.5 管道输入流-PipedInputStream管道输入流应该链接到管道输出流,管道输入流提供要写入管道输出流的所有数据字节。通常,通常数据由某个线程从PipedInputStream对象读取,并由其他线程将其写入到相应的PipedOutputStream。我们不建议对这二个对象实行单线程。因为这样可能会锁死线程。管道输入包含一个缓存区,可以在缓存区容许范围内将读操作和写操作分离。如果向链接管道输出流提供数据字节的线程不存在,则认为该管道已损毁。创建管道输入流的实例时,需要以管道输出流的实例作为输入:PipedInputStream(PipedOutputStream src);/使其连接到管道输出流src你也可以创建一个未连接的管道输入流:PipedInputStream();/创建尚未连接的PipedInputStream然后调用PiperInputStream类的connect建立与输出流的连接:void connect(PipedOutputStream src);/使此管道输入流连接到管道输出流src由于PipedOutputStream要以PipedOutputStream的实例作为输入,所以在演示实例9-14中,我们先创建了一个PipedOutStream对象os,再根据os创建PipedInputStream的对象is.最后往输出流os中写入数据,即可从is中读取数据。public class PipedInputStreamTest public static void main(String args) throws IOException PipedOutputStream os = new PipedOutputStream();PipedInputStream is=new PipedInputStream(os);byte buf = new byte3;buf0=100;buf1=101;buf2=102;os.write(buf);while(is.available()0)int c = is.read();System.out.print(char) c) );is.close();os.close();Tips该实例演示了PipedOutputStream的创建和使用,这将在下一节中讲解。通常管道的使用不像这里的实例一样,简单地建立流的连接,这样实际上并没有意义。管道流通常用在多线程的程序中,一个线程可以随机往输出流管道写入数据,另一个线程可以随时从输入流管道读取数据,达到异步传输数据。这将在下一节的PipedOutputStream实例中进行演示。4.2.6 串联输入源-SequenceInputStreamSequenceInputStream容许你连接多个InputStream流,表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,以此类推,直到到达包含最后一个输入流的文件结尾为止。它不仅可以串联两个数据源,也可以串联一个Enumeration类型的数据源列表,分别使用下面的构造函数创建:*SequenceInputStream(InputStream s1,InputStream s2);/通过记住这两个参数案例初始化新创建的SequenceInputStream(将按顺序读取这两个参数,先读取s1,然后读取s2),以提供从此SequenceInputStream读取的字节*SequenceInputStream(Enumeraiton e)/通过记住参数来创始化新创建的SequenceInputStream,该参数必须是生成运行时类型为InputStream对象的Enumeration型参数程序9-15演示了将两个文件数据源串联起来,创建一个SequenceInputStream类型的数据源并输出文件内容到控制台中。public class SequenceInputStreamTest public static void main(String args) throws IOException FileInputStream f1 =new FileInputStream(D:/work/demo/test.txt);FileInputStream f2 =new FileInputStream(D:/work/demo/test2.txt);Vector vector = new Vector();vector.add(f1);vector.add(f2);Enumeration emumeration = vector.elements();SequenceInputStream is = new SequenceInputStream(emumeration);while(is.available()0)int c =is.read();System.ou

温馨提示

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

最新文档

评论

0/150

提交评论