io-字符流与字节流

来源:互联网 发布:c语言智能2048 编辑:程序博客网 时间:2024/06/06 12:43

一,本章目标

掌握流的概念

掌握字节流与字符流的作用

掌握文件的标准操作步骤

掌握字节与字符操作的区别



二,具体内容

 2.1  流的概念

      在程序中,所有的数据都是以流的方式进行传输或者保存的,程序需要数据的时候要使用流读取数据,当程序需要将一些数据保存起来的时候,

需要使用输出流来完成。

程序中的输入和输出都是以流 的形式保存的,流中保存的实际上全都是字节文件。

2.2  字节流与字符流

在java.io包中操作文件内容的主要是两大类:字节流和字符流,两类都是分为输入和输出操作。在字节流中输出数据主要使用OutputStream完成,输入

使用InputStream,在字节流输出使用Writer类完成,输入则是使用Reader类完成。

内容操作:OutputStream,InputStream,Writer,Reader这四个类。

操作文件步骤:

①使用File类打开一个文件

②通过字节流或者字符流的子类,指定输出的位置

③进行读/写操作

④关闭输入/输出

注意:使用File类的时候路径要注意分割符。

为什么要使用字节流或者字符流的子类?

这4个IO操作类都是操作类。

IO操作属于资源操作,对于资源操作,操作的最后必须关闭,否则就有可能出现未知的错误。


2.3 字节流

字节流主要是操作byte型数据,以byte数据为准,主要操作类就是OutputStream(输出),InputStream(输入)。

Byte是字节,肯定使用字节流操作。所有的数据基本上都可以使用Byte型数据表示出来。

OutputStream类:这个类是整个io包中字节输出流的最大父类,此类定义如下:

public abstract class OutputStream extengds Object implements Closeable,Flushable

从定义上可以发现,这个类是一个抽象类,如果想要使用此类,必须通过子类实例化对象,那么如果现在要操作一个文件,则可以使用FileOutputStream类,

        通过向上转型之后,可以为OutputStream实例化。

Clonseable表示可以关闭的操作,因为程序运行到最后肯定要关闭。

Flushable表示刷新,可以清空内存中的数据。

注意:FileOutputStream类中的构造方法,需要传入一个File类的实例化对象,表示你要操作的对象。



在操作输出流的时候,也可以使用循环的方式来输出数据。



存在一个问题:文件在写入数据之后,文件之前的内容已经不存在了。为什么呢?

因为在IO的操作中默认的情况是将其覆盖的,那么如果想要执行追加的功能,则必须设置追加操作,找到FileOutputStream类中的另外一个操作方法。


使用FileOutputStream类的另外一个构造方法。




程序可以追加内容,但是没换行。如果想要换行,就需要使用“/r/n”来完成。


InputStream类:字节输入流类。

  既然程序可以项文件中写入内容,则就可以通过InputStream类从文件中把内容读取进来,首先看看InputStream类的定义:

public abstract class InputStream extends Object implements Closeable

与OutputStream类一样,InputStream本身也是一个抽象类,必须依靠其子类,如果现在是从文件中读取,子类肯定是FileInputStream。

观察FileInputStream类的构造方法:

public FileInputStream(File file) throws FileNotFoundException


内容读取了进来,但是有一些问题:

①内容中有很多空格,因为byte数据是一个1024空间大小的,把全部空格都读取进来了

改进:读取固定长度的数据



问题②:文件没这么大,但是开辟了这么大的数据空间,那么能不能根据文件大小开辟数据空间?

要想知道文件大小,可以使用File类就可以完成。使用File类的leng方法(返回时long型的数据,需要转型)。



以上方法是使用byte数组来完成的

现在使用public abstract int read()throws IOException方法一个一个地读取内容。



以上的操作只适合于知道输入流大小的时候才可以用。

那么如果不知道文件大小呢?read方法会在读取到文件末尾的时候返回一个-1。


不知道读取内容有多大的时候,就只能以读取的数据是否为-1为读完的标志。



2.3  字符流

在程序中一个字符等于2个字节,那么java提供了Reader(输入)和Writer(输出)两个专门操作字符流的类。

Writer类:字符的输出流,此类定义如下

public abstract class Writer extends Object implements Appendable,Closeable,Flushable

此类本身也是一个抽象类,如果想要使用此类,则肯定要使用其子类,如果此时是向文件中写入内容,所以应该使用FlieWriter的子类。

public FileWriter(File file) throws IOException

注意:Appendable类有一个方法,可以追加内容

字符流的操作比字节流操作方便一点,可以直接输出字符串,不用转换操作。



使用字符流默认情况下也会覆盖文件,如果想要追加内容,则在FileWriter上增加一个追加标记就可以了。



Reader类:字符输入流

Reader是使用字符的方式从文件之中取出数据,Reader类的定义如下:

public abstract class Reader extends Object implements Readable,Closeable

Reader本身也是抽象类,如果现在要从文件中读取内容,则可以直接使用FileReader的子类

FileReader的构造方法如下:

public FileReader(File file) throws FileNotFoundException

Readable接口表示可以读取。



以上是用字符数组的方式读取数据。

也可以通过循环的方式读取内容。




2.4  字节流与字符流的区别

字节流和字符流是相似的。

使用一个代码验证字符流使用到缓存。



在字节流中,即使没有关闭资源,最终也是可以输出的。



而使用字符流,没有输出任何内容,也就是说,所有的内容保存在缓冲区之中。

如果执行关闭的时候会强制性刷新缓冲区,所以可以把内容输出。

假设现在没有关闭,也可以调用flush方法强制刷新缓冲区,把内容输出。

即是:在字符流中,如果没有使用close方法关闭资源,则要使用flush方法强制刷新,这样就可以把内容输出或者输入

问题:开发中,在使用字节流好还是字符流好?

在所有的硬盘上保存文件或者是进行传输的都是以字节的方式进行,包括图片,而字符只有在内存中才会形成的,所以使用字节是最多的。


例子:copy文件