1、1File类字节流IO流概述字符流随机访问流2v 流的概念流的概念 流:是同一台计算机或网络中不同计算机之间有序运动的数据序列。输入数据流:外设流入计算机的数据序列数据流 输出数据流:计算机流向外设的数据序列数据序列:可以是原始的二进制字节数据,也可以是经过特定编码处理的有格式的数据按照数据的输入输出方式分为:输入流(按照数据的输入输出方式分为:输入流(Input Input StreamStream)和输出流()和输出流(Output StreamOutput Stream)流的分类流的分类注意:注意:对于一些设备来说,键盘就是标准的输入设备,程序要接受它提供的数据必须使用输入流,而显示器是
2、标准的输出设备,必须使用输出流向显示器输出数据。但输入流和输出流也不是绝对不变的,例如对于一个文件而言,当向其中写入数据时,它就是数据的接受者,需要使用输出流;当从该文件读取数据时,它就是数据的提供者,需要使用输入流。4按照数据处理的方式分为字节流和字符流。按照数据处理的方式分为字节流和字符流。流的分类流的分类注意:注意:如何区分字节流和字符流呢?从Java IO流类名的命名可以轻易地区分它们。一般来说,如果一个IO流的类名以Stream结尾,说明它是一个字节流,如FileInputStream、DataOutputStream等。如果一个IO流的类名以Reader或Writer结尾,说明它是
3、一个字符流,如BufferedReader,FileWriter等。5按照流的建立方式和工作原理分为节点流和过滤按照流的建立方式和工作原理分为节点流和过滤流。流。节点流类是指直接在输入输出媒介之上建立的流,一般来说标准流、非过滤字节流类可以作为节点流使用,如FileInputStream。而过滤流类是在节点流类基础上在功能上进行扩展,此时它必须先以某一个节点流对象作为过滤流的来源(即作为该过滤流的参数),然后可以修改已经读出或者写入的数据,甚至还可以简单地利用自身提供的附加方法将已经读出或者写入的数据转化成其他格式。1.IO流概述流的分类流的分类注意:注意:无论按照什么样的分类方式,针对每一个
4、具体的Java IO流类都可以把它们归属于相应的分类方式。如PipedOutputStream类是一个字节输出节点流,而BufferedReader则是一个字符输入过滤流。61.IO流概述Java IOJava IO流体系结构流体系结构71.IO流概述Java IOJava IO流体系结构流体系结构8File类字节流IO流概述字符流随机访问流9Java中每个文件和目录也是对象,每个File类的对象都表示是一个文件或目录。调用它的方法可以获得该文件或目录的属性,完成对文件和目录的操作,如创建、删除等。2.File类FileFile类类构造方法构造方法说明说明File(String filenam
5、e)根据文件的路径名创建一个新的File对象File(String parent,String child)根据文件路径名和文件名创建一个新的File对象File(File parent,String child)根据指定目录的File对象和文件名创建一个新的File对象File(URI uri)根据URI所对应的路径名创建一个新的File对象102.File类FileFile类类File file1=new File(Hello.java);File file2=new File(/);File file3=new File(file2,Hello.java);File file4=new
6、File(/,Hello.java);注意:注意:在Unix/Linux操作系统下,路径分隔符为“/”,并且系统的根目录为“/”;而在Windows和DOS下的路径分隔符为“”,而且Windows/DOS下每个磁盘分区就是一个文件系统,因此Windows/DOS可以有多个根目录。Java对这两种分隔符都支持。但是如果使用“”作为分隔符,注意要以转义字符“”来代替,例如以“c:sunjdk”表示“c:sunjdk”。11FileFile类类方法方法说明说明public boolean canRead()测试应用程序是否可以读取此抽象路径名表示的文件public boolean canWrite(
7、)测试应用程序是否可以修改此抽象路径名表示的文件public boolean exists()测试此抽象路径名表示的文件或目录是否存在public boolean isAbsolute()测试此抽象路径名是否为绝对路径名public boolean isDirectory()测试此抽象路径名表示的文件是否是一个目录public boolean isFile()测试此抽象路径名表示的文件是否是一个标准文件public boolean isHidden()测试此抽象路径名指定的文件是否是一个隐藏文件public long lastModified()返回此抽象路径名表示的文件最后一次被修改的时间p
8、ublic long length()返回由此抽象路径名表示的文件的长度;若目录则返回值不确定public boolean createNewFile()当指定的文件不存在时,使用此访问创建一个指定文件public boolean delete()删除此抽象路径名表示的文件或目录。若目录则必须为空才能删除12FileFile类类public void deleteOnExit()在虚拟机终止时,请求删除此抽象路径名表示的文件或目录public String list()返回由此抽象路径名中的文件和目录名所组成字符串数组public File listFiles()返回一个抽象路径名数组publ
9、ic boolean mkdir()创建此抽象路径名指定的目录public boolean renameTo(File dest)重新命名此抽象路径名表示的文件public boolean setLastModified(long t)设置由此抽象路径名所指定的文件或目录的最后一次修改时间public boolean setReadOnly()设置此抽象路径名指定的文件或目录为只读public static File listRoots()列出可用的文件系统根目录public int compareTo(File pathname)按字母顺序比较两个抽象路径名public String get
10、Name()返回由此抽象路径名表示的文件或目录的名称public String getParent()返回此抽象路径名的父路径名,如果此路径名无父目录则返回nullpublic File getParentFile()返回此抽象路径名的父路径名,如果此路径名无父目录则返回null13public String getPath()返回此抽象路径名public String getAbsolutePath()返回抽象路径名的绝对路径名的字符串形式public File getAbsoluteFile()返回抽象路径名的绝对路径名形式public String getCanonicalPath()返
11、回抽象路径名的规范路径名字符串public File getCanonicalFile()返回此抽象路径名的规范形式public long getFreeSpace()以字节为单位返回当前磁盘的剩余空间public long getTotalSpace()以字节为单位返回当前磁盘的总空间public long getUsableSpace()以字节为单位返回当前磁盘的可用空间FileFile类类14File类字节流IO流概述字符流随机访问流15字节流类是专门处理以字节为传输单位的IO流类。我们知道计算机中的数据处理基本上都是以字节为单位进行处理,这类数据保存的文件也称为“二进制文件”,如果要读
12、写这些二进制文件,就需要使用Java中的字节流对象。InputStream和OutputStream分别是输入字节流与输出字节流的抽象父类。16InputStreamInputStream和和OutputStreamOutputStream方法方法说明说明public int available()返回当前可读的字节数public void close()关闭输入流以释放占用的系统资源public void mark(int readlimit)在输入流的当前位置设置一个标记(相当于放一个书签)public boolean markSupported()测试输入流是否支持mark()和rese
13、t()方法public abstract int read()从输入流中读取下一个字节的数据,返回该字节的ASCII码值,如果到文件的末尾,则返回-1public int read(byte b)从输入流中读取一部分字节并将它们存放到字节数组b中,如果读取成功返回读取字节的个数,如果到文件的末尾返回-1public int read(byte b,int off,int len)从输入流中读取len个字节将它们存放到字节数组b中,并且存放到b的从off位置后面。如成功返回读取字节的个数,否则返回-1public void reset()重新设置标记到输入流中最近一次使用mark()方法指定的位
14、置。该方法需要和mark()方法结合使用public long skip(long n)从当前输入流中跳过并忽略掉n个字节的输入。返回读取的字节数 InputStream类的主要方法类的主要方法17InputStreamInputStream和和OutputStreamOutputStream OutputStream类的主要方法类的主要方法方法方法说明说明public void close()关闭输出流并释放占用的系统资源public void flush()刷新输出流并强制写出所有缓冲区的数据public abstract void write(int b)将一个指定的字节数据写到输出流中
15、public void write(byte b)将一个字节数组b中的全部数据写到输出流中public void write(byte b,int off,int len)将一个字节数组b中从off位置开始长为len的字节写到输出流18字节流类字节流类分类与作用分类与作用BufferedInputStream缓冲流,从缓冲区读取输入流BufferedOutputStream缓冲流,向缓冲区写入输出流ByteArrayInputStream访问数组,从字节数组中读取输入流ByteArrayOutputStream访问数组,向字节数组中写入输出流DataInputStream处理基本数据类型,读取
16、Java基本数据类型方法的输入流DataOutputStream处理基本数据类型,写入Java基本数据类型方法的输出流FileInputStream访问文件,读取磁盘文件的输入流FileOutputStream访问文件,向磁盘文件中写入数据的输出流FilterInputStream抽象父类过滤流包括BufferedInputStream、DataInputStream和PushbackInputStreamFilterOutputStream抽象父类过滤流包括BufferedInputStream和DataInputStreamObjectInputStream对象流,读取输入流中的对象数据O
17、bjectOutputStream对象流,向输出流中写入对象数据PushbackInputStream推回输入流,向输入流返回一个字节的输入流PipedInputStream管道输入流PipedOutputStream管道输出流PrintStream打印流,包括print()、printf()、println()等方法的输出流SequenceInputStream顺序输入流,由两个或两个以上的顺序读取的输入流组成的输入流常用的输入输出字节流子类常用的输入输出字节流子类InputStreamInputStream和和OutputStreamOutputStream19标准流标准流 语言包java
18、.lang中的System类管理标准输入/输出流和错误流。System.in,从InputStream中继承而来,用于从标准输入设备中获取输入数据(通常是键盘)。System.out,从PrintStream中继承而来,把输出送到缺省的显示设备(通常是显示器)。System.err,也是从PrintStream中继承而来,把错误信息送到缺省的显示设备(通常是显示器)。每当每当main方法被执行时,就自动生成上述三个对象。方法被执行时,就自动生成上述三个对象。3.字节流20public class ReadFromKB public static void main(String args)tr
19、y byte bArray=new byte128;String str;System.out.println(Enter something Using Keyborad:);System.in.read(bArray);str=new String(bArray,0);System.out.print(You entered:);System.out.println(str);catch(IOException ioe)System.out.println(ioe.toString();标准流(例子)标准流(例子)从键盘中获取数据从键盘中获取数据21构造方法构造方法说明说明FileInpu
20、tStream(File file)根据File类对象创建一个文件字节输入流对象FileInputStream(String name)根据字符串name创建一个文件字节输入流对象,name代表路径和文件名FileInputStreamFileInputStream和和FileOutputStreamFileOutputStreamFileInputStream fis=new FileInputStream(c:Hello.java);File file=new File(c:Hello.java);FileInputStream fin=new FileInputStream(file);
21、FileInputStream类的主要构造方法类的主要构造方法22FileInputStreamFileInputStream和和FileOutputStreamFileOutputStream构造方法构造方法说明说明FileOutputStream(File file)创建一个向file中写入数据的文件输出流FileOutputStream(File file,boolean append)创建一个是否向file尾部追加数据的文件输出流FileOutputStream(String name)创建一个向name中写入数据的输出文件流FileOutputStream(String name,b
22、oolean append)创建一个是否向name尾部追加数据的输出文件流FileOutputStream类的构造方法类的构造方法FileOutputStream fos1=new FileOutputStream(f1.txt);FileOutputStream fos2=new FileOutputStream(f2.txt,true);FileOutputStream fos3=new FileOutputStream(new File(f3.txt);FileOutputStream fos4=new FileOutputStream(new File(f4.txt),false);2
23、3java.io包中提供了FilterInputStream类和FilterOutputStream类分别对其他输入/输出流进行特殊处理,它们在读/写数据的同时可以对数据进行特殊处理。另外它们还提供了同步机制,使得某一时刻只有一个线程可以访问一个输入/输出流。FilterInputStream类和FilterOutputStream类都是抽象类,因此它们均不能实例化对象。FilterInputStream类有3个子类,它们分别是BufferedInputStream、DataInputStream和PushbackInputStream;FilterOutputStream类也有3个子类,分别
24、是BufferedOutputStream、DataOutputStream和PrintStream。过滤字节流过滤字节流24BufferedInputStream和BufferedOutputStream类称为缓冲字节流,它引入了针对内存缓冲区的操作,从而提高了读写数据的效率。BufferedInputStreamBufferedInputStream和和BufferedOutputStreamBufferedOutputStream构造方法构造方法说明说明BufferedInputStream(InputStream in)创建一个缓冲输入流并连结节点输入流in,缓冲区默认大小为32个字节
25、BufferedInputStream(InputStream in,int size)创建一个缓冲输入流并连结节点输入流in,缓冲区默认大小为size个字节BufferedOutputStream(OutputStream out)创建一个新的缓冲输出流,将数据写入到节点输出流outBufferedOutputStream(OutputStream out,int size)创建一个新的缓冲输出流,将缓冲区大小为size字节的数据写入到节点输出流out25import java.io.*;public class BufferedInputStreamDemo public static v
26、oid main(String args)FileInputStream fis=null;FileOutputStream fos=null;BufferedInputStream bis=null;BufferedOutputStream bos=null;tryfis=new FileInputStream(“MyHeartWillGoOn.mp3);/使用节点流FileInputStream对象连结缓冲输入流,并指定缓冲区大小为1024bis=new BufferedInputStream(fis,1024);fos=new FileOutputStream(“goon.mp3);/使
27、用节点流FileOutputStream对象连结缓冲输出流,并指定缓冲区大小为1024bos=new BufferedOutputStream(fos,1024);BufferedInputStreamBufferedInputStream和和BufferedOutputStreamBufferedOutputStream26byte buffer=new byte1024;int len=0;/循环读取输入流while(len=bis.read(buffer)!=-1)/将buffer数组中的数据写入到输出流bos.write(buffer,0,len);/最近一次读取的数据,可能达不到10
28、24字节,因此强制清空缓冲区bos.flush();catch(Exception e)e.printStackTrace();finally/关闭文件流trybos.close();fos.close();catch(IOException e)e.printStackTrace();BufferedInputStreamBufferedInputStream和和BufferedOutputStreamBufferedOutputStream27java.io包中含有两个接口DataInput和DataOutput,这两个接口设计了一种较为高级的数据输入输出方式:除了可处理字节和字节数组外,
29、还可以处理int、float、boolean等基本数据类型,这些数据在文件中的表示方式和它们在内存中的一样,无须转换,它们相应地提供了很多处理基本数据类型的方法,如DataInput提供了read()、readInt()、readByte(),DataOutput提供了write()、writeChar()、writeFloat()。而数据流类DataInputStream和DataOutputStream分别实现了DataInput和DataOutput接口,在提供了字节流的读写手段的同时,还可以实现对文件中的不同数据类型的读写。DataInputStreamDataInputStream和
30、和DataOutputStreamDataOutputStream28在编译程序的词法分析阶段,经常需要超前读入一个字节以界定当前词的属性,然后再从缓冲区将该字节退回(因为下面的处理可能还会用到该字节)。PushbackInputStream类就提供了这样的能力,它提供了一个方法将刚刚读入的字节退回到输入流中去。PushbackInputStreamPushbackInputStream构造方法和方法构造方法和方法说明说明PushbackInputStream(InputStream in)创建一个过滤流对象,允许它返回一个字节到节点流in中PushbackInputStream(InputS
31、tream in,int size)他建一个过滤流对象,它提供了长度为size个字节的缓冲区,最多可退回size个字节返回到节点流inpublic void unread(int b)退回一个字节,这个字节由低8位构成public void unread(byte b)退回byte数组b中的所有字节public void unread(byte b,int off,int len)退回byte数组b中从off位置开始的len个字节29PushbackInputStreamPushbackInputStreamimport java.io.*;public class PushbackInput
32、StreamDemo public static void main(String args)throws IOException/声明一个字符串表达式String s=if(a=4)a=0;n;/将s转化为字节数组byte buf=s.getBytes();/使用字节数组输入流,读取字节数组bufByteArrayInputStream bais=new ByteArrayInputStream(buf);/以字节数组输入流对象作为节点流,连结PushbackInputStream对象PushbackInputStream pis=new PushbackInputStream(bais);
33、int c;30while(c=pis.read()!=-1)switch(c)case=:if(c=pis.read()=)System.out.print(等于);else System.out.print(大于);pis.unread(c);break;default:System.out.print(char)c);break;PushbackInputStreamPushbackInputStream31PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据类型的数据值。与其他输出流不同,PrintStream 不会抛出 IOException;而是通过chec
34、kError方法设置测试的内部标志来检测异常。另外,PrintStream可在写入字节数组之后会自动调用flush()方法。PrintStream类提供了多个构造方法以及重载了多个println()方法以便能够打印多种数据类型的数据值。PrintStreamPrintStream32PrintStream(File file)创建具有指定文件且不带自动行刷新的新打印流PrintStream(File file,String csn)创建具有文件名和字符集且不带自动刷新的打印流PrintStream(OutputStream out)创建新的打印流PrintStream(OutputStream
35、 out,boolean flush)创建新的打印流,并指定是否自动刷新PrintStream(OutputStream out,boolean flush,String enc)创建新的打印流,指定是否刷新和编码方式PrintStream(String fileName)创建具有文件名且不带自动刷新的新打印流PrintStream(String fileName,String csn)创建具有指定文件名和字符集无自动刷新的打印流public PrintStream append(char c)向此输出流追加指定字符,等价于print()public PrintStream format(St
36、ring format,Object.args)以指定格式字符串和参数将字符串写入输出流public PrintStream printf(String format,Object.args)以指定的格式打印objpublic void println(Object x)打印obj,可以是基本数据类型或对象,支持换行public void print(Object obj)打印obj,obj可以是基本数据类型,也可以是对象public void write(int b)将字节b写入到此流PrintStreamPrintStream33java.io包中提供了类PipedInputStream和
37、PipedOutputStream作为管道的输入/输出流。管道输入流作为一个通信管道的接收端,管道输出流则作为发送端。管道流必须是输入流输出流同时并用,即在使用管道前,两者必须进行连接。管道字节流管道字节流34PipedInputStream pis=new PipedInputStream();PipedOutputStream pos=new PipedOutputStream();pis.connect(pos);pos.connect(pis);管道字节流管道字节流PipedInputStream pis=new PipedInputStream();/实例化管道输出流对象pos,并利
38、用构造方法连结pisPipedOutputStream pos=new PipedOutputStream(pis);无论PipedInputStream和PipedOutputStream类都提供了connect()方法,可以使用connect()方法建立一个管道进行数据传输。管道输入/输出流可以用两种方式进行连接,一种方式是使用connect()方法:另外一种连接方式是直接使用构造方法进行连接:35java.io包中提供了ByteArrayInputStream类和ByteArrayOutputStream类,将内存中 byte类型的数组当作流输入来源、输出目的地。ByteArrayInp
39、utStream可以从指定的字节数组中读取数据;ByteArrayOutputStream中提供了缓冲区可以存放数据(缓冲区大小可以在构造方法中设定,缺省为32字节),可以用write()方法向其中写入数据,然后用toByteArray()方法将缓冲区中的有效字节写到字节数组中去内存读写流内存读写流构造方法构造方法说明说明ByteArrayInputStream(byte buf)创建一个内存输入流,使用buf作为其缓冲区数组ByteArrayInputStream(byte buf,int offset,int length)创建一个内存输入流,使用buf作为其缓冲区数组ByteArrayO
40、utputStream()创建一个内存输出流ByteArrayOutputStream(int size)创建一个缓冲区容量为size字节的内存输出流36java.io包中还提供了SequenceInputStream类,称为顺序输入流,它能使应用程序可以将几个输入流顺序地连接起来,让程序员看起来就像是一个比较长的流一样。顺序输入流提供了将多个不同的输入流统一为一个输入流的功能,这使得程序可能变得更加简洁。SequenceInputStream类提供了一个构造方法:SequenceInputStream(InputStreams1,InputStreams2),可以将两个输入流s1、s2按照先
41、后顺序合并为一个输入流。顺序流顺序流37对象流对象流 对象的持续性(Persistence)能够记录自己的状态以便将来再生的能力,叫对象的持续性。对象的串行化(Serialization)对象通过写出描述自己状态的的数值来记录自己的过程叫串行化。串行化的主要任务是写出对象实例变量实例变量的数值,如果变量是另一个对象的引用,则引用的对象也要串行化。这个过程是递归的。n 对象流 能够输入输出对象的流称为对象流。可以将对象串行化后通过对象输入输出流写入文件或传送到其它地方。3.字节流38 在Java中,允许可串行化的对象可串行化的对象在通过对象流进行传输。只有实现Serializable接口的类才能
42、被串行化,Serializable接口中没有任何方法,当一个类声明实现Serializable接口时,只是表明该类加入对象串行化协议。public class Student implements Serializable int id;String name;int age;String department;public Student(int id,String name,int age,String department)this.id=id;this.name=name;this.age=age;this.department=department;对象流对象流3.字节流39 要串行
43、化一个对象,必须与一定的对象输出/输入流联系起来,通过对象输出流将对象状态保存下来(将对象保存到文件中,或者通过网络传送到其他地方),再通过对象输入流将对象状态恢复。类ObjectOutputStream和ObjectInputStream分别继承了接口ObjectOutput和ObjectInput,将数据流功能扩展到可以读写对象,前者用writeObject()方法可以直接将对象保存到输出流中,而后者用readObject()方法可以直接从输入流中读取一个对象。对象流对象流3.字节流40对象流对象流 从某种意义来看,对象流与数据流是相类似的,也具有过滤流的特性。利用对象流来输入/输出对象时
44、,也不能单独使用,需要与其他的流连接起来。q 对象是可串行化的q 使用对象流3.字节流41public class Objectser public static void main(String args)Student stu=new Student(981036,“Li Ming”,16,“CSD”);try FileOutputStream fo=new FileOutputStream(“data.ser”);ObjectOutputStream so=new ObjectOutputStream(fo);so.writeObject(stu);so.close();catch(Ex
45、ception e)System.out.println(e);对象流:例子(对象的存储)对象流:例子(对象的存储)42public class ObjectRecov public static void main(String args)Student stu;try FileInputStream fi=new FileInputStream(“data.ser”);ObjectInputStream si=new ObjectInputStream(fi);stu=(Student)si.readObject();si.close();catch(Exception e)System.
46、out.println(e);System.out.println(“ID:”+stu.id+“name:”+stu.name+“age:”+stu.age+“dept.:”+stu.department);对象流:例子(对象的存储)对象流:例子(对象的存储)43对象流对象流定制对象的串行化定制对象的串行化:当一个对象串行化时,如果希望该对象的某些属性不被保存,可以通过在类定义中重写readObject()和WriteObject()方法来实现。3.字节流44 串行化只能保存对象的非静态成员变量(实例变量)非静态成员变量(实例变量),而不能保存任何成员方法和静态成员变量,并且保存的只是变量的值
47、,对于变量的任何修饰符都不能保存。对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的,如Thread对象或流对象。对于这样的成员变量,必须用transient关键字标明,否则编译器将报错。任何用transient关键字标明的成员变量,都不会被保存。另外,串行化可能涉及将对象存放到磁盘上或在网络上发送数据,这时会产生安全问题。对于一些需要保密的数据,不应保存在永久介质中(或者不应简单地不加处理地保存下来),为了保证安全,应在这些变量前加上transient关键字。对象流对象流3.字节流45File类字节流IO流概述字符流随机访问流46同类InputStream和OutputStre
48、am一样,Reader和Writer也是抽象类,只提供了一系列用于字符流处理的接口。ReaderReader和和WriterWriter方法方法说明说明public int read()读取单个字符,返回一个0-65535范围内的整数public int read(char c)将字符读入数组,返回读取的字符数,如到末尾返回-1public abstract int read(char c,int o,int l)将字符读入数组的一部分,返回读取的字符数,如到末尾返回-1public long skip(long n)跳过n个字符public boolean ready()判断是否准备读取此流
49、public boolean markSupported()判断是否支持mark()方法和reset()方法public void mark(int readAheadLimit)标记流中的当前位置public void reset()重置流,若使用mark()标记该流,则尝试在此位置重新定位该流public abstract void close()关闭流47ReaderReader和和WriterWriter方法方法说明说明public Writer append(char c)将字符c追加到此输出字符流public abstract void flush()刷新此字符输出流public
50、abstract void close()关闭该字符输出流public void write(String str)写入字符串strpublic void write(int c)写入字符cpublic void write(char cbuf)写入字符数组cbufpublic abstract void write(char cbuf,int off,int len)写入字符组cbuf从位置off开始长度为len的部分元素public void write(String str,int off,int len)写入字符串str从off位置开始长度为len的子串48常见的字符流常见的字符流字节