码迷,mamicode.com
首页 > 编程语言 > 详细

java IO

时间:2016-08-23 20:38:40      阅读:289      评论:0      收藏:0      [点我收藏+]

标签:

java IO

输入和输出

可以将 Java 库的 IO 类分割为输入与输出两个部分,通过继承,从 InputStream(输入流)衍生的所有类都拥有名为 read()的基本方法,用于读取单个字节或者字节数组。类似地,从 OutputStream 衍生的所有类都拥有基本方法 write(),用于写入单个字节或者字节数组。

InputStream 的类型

InputStream 的作用是标志那些从不同起源地产生输入的类。
ByteArrayInputStream  允许内存中的一个缓冲区作为 InputStream 使用 从中提取字节的缓冲区/作为一个数据源使用。通过将其同一个 FilterInputStream 对象连接,可提供一个有用的接口
StringBufferInputStream   将一个 String 转换成 InputStream 一个 String(字串)。基础的实施方案实际采用一个 StringBuffer(字串缓冲)/作为一个数据源使用。通过将其同一个 FilterInputStream 对象连接,可提供一个有用的接口
FileInputStream   用于从文件读取信息 代表文件名的一个 String,或者一个 File 或 FileDescriptor 对象/作为一个数据源使用。通过将其同一个 FilterInputStream 对象连接,可提供一个有用的接口
PipedInputString 产生为相关的 PipedOutputStream 写的数据。实现了“管道化”的概念 PipedOutputStream   作为一个数据源使用。通过将其同一个 FilterInputStream 对象连接,可提供一个有用
的接口
SequenceInputStream    将两个或更多的 InputStream 对象转换成单个 InputStream 使用 两个InputStream 对象或者一个 Enumeration,用于 InputStream 对象的一个容器/作为一个数据源使用。通过将其同一个FilterInputStream 对象连接,可提供一个有用的接口

OutputStream的类型

ByteArrayOutputStream 在内存中创建一个缓冲区。我们发送给流的所有数据都会置入这个缓冲区。 可选缓冲区的初始大小 用于指出数据的目的地。若将其同FilterOutputStream 对象连接到一起,可提供一个有用的接口
FileOutputStream 将信息发给一个文件 用一个 String 代表文件名,或选用一个 File 或 FileDescriptor 对象/用于指出数据的目的地。若将其同 FilterOutputStream 对象连接到一起,可提供一个有用的接口
PipedOutputStream 我们写给它的任何信息都会自动成为相关的 PipedInputStream 的输出。实现了“管道化”的概念PipedInputStream/为多线程处理指出自己数据的目的地/将其同FilterOutputStream 对象连接到一起,便可提供一个有用的接口

FilterInputStream 的类型

DataInputStream 与 DataOutputStream 联合使用,使自己能以机动方式读取一个流中的基本数据类型( int,char,long 等等) InputStream/包含了一个完整的接口,以便读取基本数据类型
BufferedInputStream 避免每次想要更多数据时都进行物理性的读取,告诉它“请先在缓冲区里找”InputStream,没有可选的缓冲区大小/本身并不能提供一个接口,只是发出使用缓冲区的要求。要求同一个接口对象连接到一起
LineNumberInputStream 跟踪输入流中的行号;可调用 getLineNumber()以及 setLineNumber(int) 只是添加对数据行编号的能力,所以可能需要同一个真正的接口对象连接
PushbackInputStream 有一个字节的后推缓冲区,以便后推读入的上一个字符 InputStream/通常由编译器
在扫描器中使用,因为 Java 编译器需要它。一般不在自己的代码中使用

FilterOutputStream 的类型

DataOutputStream 与 DataInputStream 配合使用,以便采用方便的形式将基本数据类型( int, char, long,等)写入一个数据流 OutputStream/包含了完整接口,以便我们写入基本数据类型

PrintStream 用于产生格式化输出。 DataOutputStream 控制的是数据的“存储”,而 PrintStream 控制的是“显示” OutputStream,可选一个布尔参数,指示缓冲区是否与每个新行一同刷新/对于自己的OutputStream 对象,应该用“ final”将其封闭在内。可能经常都要用到它
BufferedOutputStream 用它避免每次发出数据的时候都要进行物理性的写入,要求它“请先在缓冲区里找”。可调用 flush(),对缓冲区进行刷新 OutputStream,可选缓冲区大小/本身并不能提供一个接口,只是发出使用缓冲区的要求。需要同一个接口对象连接到一起

RandomAccessFile 

RandomAccessFile 用于包含了已知长度记录的文件,以便我们能用 seek()从一条记录移至另一条;然后读取或修改那些记录。各记录的长度并不一定相同;只要知道它们有多大以及置于文件何处即可。首先,我们有点难以相信 RandomAccessFile 不属于 InputStream 或者 OutputStream 分层结构的一部分。除了恰巧实现了 DataInput 以及 DataOutput(这两者亦由 DataInputStream 和 DataOutputStream 实现)接口之外,它们与那些分层结构并无什么关系。它甚至没有用到现有InputStream 或 OutputStream 类的功能——采用的是一个完全不相干的类。该类属于全新的设计,含有自己的全部(大多数为固有)方法。之所以要这样做,是因为 RandomAccessFile 拥有与其他 IO 类型完全不同的行为,因为我们可在一个文件里向前或向后移动。不管在哪种情况下, 它都是独立运作的,作为 Object 的一个“直接继承人”使用。

File

File 类它既代表一个特定文件的名字,也代表目录内一系列文件的名字。若代表一个文件集,便可用list()方法查询这个集,返回的是一个字串数组。之所以要返回一个数组,而非某个灵活的集合类,是因为元素的数量是固定的。而且若想得到一个不同的目录列表,只需创建一个不同的 File 对象即可。事实上,“ FilePath”(文件路径)似乎是一个更好的名字。本节将向大家完整地例示如何使用这个类,其中包括相关的 FilenameFilter(文件名过滤器)接口。
File 类并不仅仅是对现有目录路径、文件或者文件组的一个表示。亦可用一个 File 对象新建一个目录,甚至创建一个完整的目录路径—— 假如它尚不存在的话。亦可用它了解文件的属性(长度、上一次修改日期、读/写属性等),检查一个 File 对象到底代表一个文件还是一个目录,以及删除一个文件等等。

输入流

缓冲的输入文件:为打开一个文件以便输入,需要使用一个 FileInputStream,同时将一个 String 或 File 对象作为文件名使
用。为提高速度,最好先对文件进行缓冲处理,从而获得用于一个BufferedInputStream 的构建器的结果句柄。为了以格式化的形式读取输入数据,我们将那个结果句柄赋给用于一个 DataInputStream 的构建器。DataInputStream 是我们的最终( final)对象,并是我们进行读取操作的接口。
从内存输入:这一部分采用已经包含了完整文件内容的 String s2,并用它创建一个 StringBufferInputStream(字串缓冲输入流) —— 作为构建器的参数,要求使用一个 String,而非一个 StringBuffer)。随后,我们用 read()依次读取每个字符,并将其发送至控制台。注意read()将下一个字节返回为 int,所以必须将其造型为一个char,以便正确地打印。
格式化内存输入:StringBufferInputStream 的接口是有限的,所以通常需要将其封装到一个DataInputStream 内,从而增强
它的能力。然而,若选择用 readByte()每次读出一个字符,那么所有值都是有效的,所以不可再用返回值来侦测何时结束输入。相反,可用 available()方法判断有多少字符可用。

输出流

保存与恢复数据:PrintStream 能格式化数据,使其能按我们的习惯阅读。但为了输出数据,以便由另一个数据流恢复,则需
用一个 DataOutputStream 写入数据,并用一个 DataInputStream 恢复(获取)数据。当然,这些数据流可以是任何东西,但这里采用的是一个文件,并进行了缓冲处理,以加快读写速度。注意字串是用 writeBytes()写入的,而非 writeChars()。若使用后者,写入的就是 16 位 Unicode 字符。由于 DataInputStream 中没有补充的“ readChars”方法,所以不得不用 readChar()每次取出一个字符。所以对 ASCII 来说,更方便的做法是将字符作为字节写入,在后面跟随一个新行;然后再用 readLine()将字符当
作普通的 ASCII 行读回。
writeDouble()将 double 数字保存到数据流中,并用补充的 readDouble()恢复它。但为了保证任何读方法能够正常工作,必须知道数据项在流中的准确位置,因为既有可能将保存的 double 数据作为一个简单的字节序列读入,也有可能作为 char 或其他格式读入。所以必须要么为文件中的数据采用固定的格式,要么将额外的信息保存到文件中,以便正确判断数据的存放位置
读写随机访问文件:RandomAccessFile 与 IO 层次结构的剩余部分几乎是完全隔离的,尽管它也实现了DataInput 和 DataOutput 接口。所以不可将其与 InputStream 及 OutputStream 子类的任何部分关联起来。尽管也许能将一个 ByteArrayInputStream 当作一个随机访问元素对待,但只能用 RandomAccessFile打开一个文件。必须假定 RandomAccessFile 已得到了正确的缓冲,因为我们不能自行选择。可以自行选择的是第二个构建器参数:可决定以“只读”( r)方式或“读写”( rw)方式打开一个RandomAccessFile 文件。
使用 RandomAccessFile 的时候,类似于组合使用 DataInputStream 和 DataOutputStream(因为它实现了等
同的接口)。

对象序列化

它面向那些实现了Serializable 接口的对象,可将它们转换成一系列字节,并可在以后完全恢复回原来的样子。这一过程亦可
通过网络进行。这意味着序列化机制能自动补偿操作系统间的差异。换句话说,可以先在Windows 机器上创建一个对象,对其序列化,然后通过网络发给一台 Unix 机器,然后在那里准确无误地重新“装配”。不必关心数据在不同机器上如何表示,也不必关心字节的顺序或者其他任何细节。
“持久化”意味着对象的“生存时间”并不取决于程序是否正在执行—— 它存在或“生存”于程序的每一次调用之间。通过序列化一个对象,将其写入磁盘,以后在程序重新调用时重新恢复那个对象,就能圆满实现一种“持久”效果。之所以称其为“有限”,是因为不能用某种“ persistent”(持久)关键字简单地地定义一个对象,并让系统自动照看其他所有细节问题(尽管将来可能成为现实)。相反,必须在自己的程序中明确地序列化和组装对象。
对象的序列化处理非常简单,只需对象实现了 Serializable 接口即可(该接口仅是一个标记,没有方法)。

序列化的控制

通过实现 Externalizable 接口,用它代替 Serializable 接口,便可控制序列化的具体过程。这个Externalizable 接口扩展了 Serializable,并增添了两个方法: writeExternal()和 readExternal()。在序列化和重新装配的过程中,会自动调用这两个方法,以便我们执行一些特殊操作

java IO

标签:

原文地址:http://blog.csdn.net/wojiaohuangyu/article/details/52294003

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!