输入和输出流

  当个程序需要读取磁盘上的数据或将程序得到的数据存储到磁盘时,就可以使用输入和输出流,简称I/O流。Java的SDK提供了各式

的流类,用以获取不同类别的数据。I/O流提供了一条通道的程序,可以使用这条程序读取“源”中的数据,或把数据送入到目的地。

在Java的IO流库中,提供了大量的流类,其中有4个比较重要的抽象类:InputStream(字节输入流);Read(字符输出流);

OutStream(字节输出流);Writer(字符输出流)。如下图:J2 SDK提供的所有流类都继承与以下4个抽象类:

(所有的输入和输出都是以程序为起点出发的,这样便于理解输入流和输出流的区别):



A,文件字节流

1,FiltInputStram类

FileInuotStram类是继承与InputStream类的子类,称为字节输入流,是按字节读取文件中的数据。其3个构造方法如下:

FileInputStream(File file) 

通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。

FileInputStream(FileDescriptor fdObj) 

通过使用文件描述符 fdObj 创建一个 FileInputStream,该文件描述符表示到文件系统中某个实际文件的现有连接

FileInputStream(String name) 

通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。

例子:


当输入流读取文件时候,可能发生错误。比如:读取的文件不存在,会抛出FileNotFoundException异常,就会产生IO错误,就必须使用try-catch块检查

发生的错误并处理或者声明这个异常。上面例子用到了try-catch的多态。

介绍一下文件字节输入\输出流的常用方法(输入流和输出流一般是对应的,方法基本相同):

int read()
从此输入流中读取一个数据字节。读取到结尾会返回-1;

void close()
关闭此文件输入流并释放与此流有关的所有系统资源。(切记用完要关闭,把流比成水管,打开了,用完了就要关闭)

int read(byte[] b)
从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中


2,FileOutputStream类

该类是与FileInputStream对应的类,同样继承于FileStream类。提供了程序向文件的写入能力。构造方法与FileInputStream类大同小异。

如果写入的文件地址不存在,就会创建一个与指定路径相同的文件,如果指向的文件是存在的,输出流就会刷新该文件。

方法与FileInputStram一样,至少没有返回值:

void write(byte[] b)
将 b.length 个字节从指定 byte 数组写入此文件输出流中

void write(int b)
将指定字节写入此文件输出流。

void write(byte[] b, int off, int len)
将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。

例子:上图


B:文件字符流

1,FileReader类

FileReader类是继承于Reader类的子类,称为文件字符输入流,读取方式是按字符的读取文件的。由于中国字在文件是占2个字节的,

如果使用字节流,读取文件会出现乱码现象。创建对象可以用以下构造方法;

FileReader(String fileName)
在给定从中读取数据的文件名的情况下创建一个新 FileReader。

FileReader(FileDescriptor fd)
在给定从中读取数据的 FileDescriptor 的情况下创建一个新 FileReader。

FileReader(File file)
在给定从中读取数据的 File 的情况下创建一个新 FileReader。

其常用的方法有:

int read()
从文件中读取单个字符。

int read(char[] cbuf)
将字符读入数组

close()
关闭该流并释放与之关联的所有资源。



结果打印出来,其中的汉字并没有乱码。


2,FileWriter类

FileWriter类继承于Writer的子类,提供了文件的写入功能,称为文件字符输出流,按字符将数据写入文件中,常用方法与FileReader一样。

跟其字节输出流一样的,如果写入的文件地址不存在,就会创建一个与指定路径相同的文件,如果指向的文件是存在的,输出流就会刷新该文件。

但是可以使用FileWriter类的具有刷新功能的构造方法创建指向文件的输出流:

FileWriter(File file, boolean append)
根据给定的 File 对象构造一个 FileWriter 对象。

FileWriter(String fileName, boolean append)
根据给定的文件名以及指示是否附加写入数据的 boolean 值来构造 FileWriter 对象。

当用该构造方法是,指定参数append值为true,在文件已经存在的情况下,不会刷新,可以在源文件下继续输出。

例子:


两者的区别:字节流:通常用来读取二进制数据,如图象和声音。

字符流:以Unicode字符为单位从stream中读取或往stream中写入信息。中文不会产生乱码

实际上:实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作文件。



C,缓冲流

1,BufferedReader流/BufferedInputStream流

BufferedReader类/BufferedInputStream类创建的对象称为缓冲输入流,该输入流的指向必须是个Reader\InputStream流,

称为BufferdeReader\Reader\InputStream流的底层流,底层流负责数据读入缓冲区。相当于水管外面套一一个大水管,

可以调用一些新的方法,同时也提高了读写效率。最主要的是缓冲流的方法,一般外套缓冲就是调用其方法:

常用的构造方法:BufferedReader(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流,传入的是Reader流的子类。

String readLine()
读取一个文本行。最为常用的方法

void mark(int readAheadLimit)
标记流中的当前位置。

void reset()
将流重置到最新的标记

long skip(long n)
跳过字符。

void close()
关闭该流并释放与之关联的所有资源。

例子:



bis.reset()返回到标记点,有重写了一次


2,BufferedWriter流和BufferedOutputStram流

BufferedWriter类/BufferedOutputStream类创建的对象称为缓冲输出流,该输入流的指向必须是个Write'r\OutputStream流,

称为BufferedWriter类/BufferedOutputStream流的底层流,底层流负责数据读入缓冲区。相当于水管外面套一一个大水管,

可以调用一些新的方法,同时也提高了读写效率。最主要的是缓冲流的方法,一般外套缓冲就是调用其方法:

常用的构造方法:BufferedWriter(Reader in) 创建一个使用默认大小输入缓冲区的缓冲字符输入流,传入的是Write'r\OutputStream流的子类。

常用方法:

void close()
关闭此流,但要先刷新它

void flush()
刷新该流的缓冲

void newLine()
写入一个行分隔符。

void write(char[] cbuf, int off, int len)
写入字符数组的某一部分。

void write(int c)
写入单个字符

void write(String s, int off, int len)
写入字符串的某一部分。

缓冲输出流可以调用newLine()方法,可以向文件中添加一个换行

例子:



3,实用例子:标准化考试:


使用输入流读取试卷,,每次显示一个题目,等待考生输入答案。完成所有题目后,显示出用户得分


输出结果:



D,数据流

DataInputStream/DataOutputStream流

DataInputStream/DataOutputStream类创建的对象称为数据输入流和数据输出流,它们允许程序按照机器无关的风格模式

读取Java原始数据,也就是说,当读取一个数值时,不在关心这个数值应当有多少个字节。

DataInputStream/DataOutputStream两组的构造方法:

DataInputStream(IntputStream in)---传入的为IntputStream的子类

DataOutputStream(OutStream out)--传入的为OutputStream的子类

两者的常用方法:(写出一种,两者一样)

void flush() -----清空此数据输出流

int size() --返回计数器 written 的当前值,即到目前为止写入此数据输出流的字节数。

void write(byte[] b, int off, int len) ---将指定 byte 数组中从偏移量 off 开始的 len 个字节写入基础输出流。

void write(int b) --- 将指定字节(参数 b 的八个低位)写入基础输出流。

void writeBoolean(boolean v) --- 将一个 boolean 值以 1-byte 值形式写入基础输出流。

void writeByte(int v) ---将一个 byte 值以 1-byte 值形式写出到基础输出流中

void writeBytes(String s) ---将字符串按字节顺序写出到基础输出流中。

void writeChar(int v) --- 将一个 char 值以 2-byte 值形式写入基础输出流中,先写入高字节。

void writeChars(String s) ---将字符串按字符顺序写入基础输出流。

writeDouble(double v) ---使用 Double 类中的 doubleToLongBits 方法将 double 参数转换为一个 long 值,

然后将该 long 值以 8-byte 值形式写入基础输出流中,先写入高字节。

writeFloat(float v) ---使用 Float 类中的 floatToIntBits 方法将 float 参数转换为一个 int 值,

然后将该 int 值以 4-byte 值形式写入基础输出流中,先写入高字节。

void writeInt(int v) ---将一个 int 值以 4-byte 值形式写入基础输出流中,先写入高字节。

void writeLong(long v) --- 将一个 long 值以 8-byte 值形式写入基础输出流中,先写入高字节。

void writeShort(int v) ---将一个 short 值以 2-byte 值形式写入基础输出流中,先写入高字节。

void writeUTF(String str) ---以与机器无关方式使用 UTF-8 修改版编码将一个字符串写入基础输出流。

例子:




E,对象流

ObjectInputStream/ObjectOutStream类分别是InoutStream/OutputStream的子类,被称为对象输入流和对象输出流。

对象输出流可以使用writerObject(Object obj)方法将一个对象obj写入源中,对象输入流使用readObject()从源中读取

一个对象到程序中。

ObjectInputStream/ObjectOutStream的构造方法分别为:

ObjectInputStream(InputStream in)---传入输入流的实现类

ObjectInputStream(InputStream in)---传入输出流的实现类

如:FileOutputStream fos = new FileOutputStream("f:\\javafile\\object\\io\\object.dat");
ObjectOutputStream oos = new ObjectOutputStream(fos);

使用对象流写入或读取对象时,要保证对象是序列化的。这是为了保证能把对象能写入文件中,并能将对象正确读出。

固读写的对象,其类必须要实现Serializable接口,那么这个类创建的对象就是序列化对象。但是不用实现Serializable

接口中的方法,该方法是不可见的,JVM运行会自动执行接口中的方法。注意:使用对象流把一个对象写入到文件时

不仅保证该对象是序列化的,而且该对象的成员变量也必须是序列化的。


使用对象流获取一个序列化对象的克隆,只需将该对象写入对象输出流,然后用对象输入流读取回对象就是一个克隆。

克隆出的对象实体的变化不会引起原对象实体的变化。




总结:要了解输入和输出流几种实现类的用法,和不同之处。

Buffered流的方法要掌握,读取行和换行方法。

要学会如何将对象实现序列化(实现Serizlizable接口和外套DateOutputStream/DateInputStream)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值