IO流2

来源:互联网 发布:des算法实现 编辑:程序博客网 时间:2024/06/05 16:16

PipedOutputStream类:

以前读取流和写入流操作需要中转,读的流将数据读入数组,写入流读取数组进行写入。而管道流实现了输入输出同时进行。

管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从PipedInputStream 对象读取,并由其他线程将其写入到相应的PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。

 

构造函数

PipedOutputStream (PipedInputStream dst)
          创建PipedOutputStream,使其连接到管道输入流dst

常用方法

void

write(byte[] b, int off, int len)
          将 len 字节从初始偏移量为 off 的指定 byte 数组写入该管道输出流。

 

例子


在管道输入流和输出流中,用到的方法为阻塞式方法,即如果没有数据进来便进行等待不往下执行,并释放执行权。

 

RandomAccessFile类:

该类不算是IO体系中的类,而是直接继承自Object。通过文件指针,对文件进行操作(只能操作模式)。可通过getPointer获取指针,通过seek改变指针位置。

构造函数:

RandomAccessFile(File file,String mode)
          创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。

RandomAccessFile(String name,String mode)
          创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。

这里的mode为对文件的操作模式:

 

其他操作:

 double

readDouble()
          从此文件读取一个 double

 void

writeFloat(float v)
          
使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个int,然后按四字节数量将该int 值写入该文件,先写高字节。

 

可以操作基本数据类型。

 void

write(int b)
          向此文件写入指定的字节。

写入字节,只能写低八位。

 

 void

write(byte[] b, int off, int len)
          将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。

void

close()
         
 关闭此随机访问文件流并释放与该流关联的所有系统资源。

 int

read(byte[] b, int off, int len)
          将最多 len 个数据字节从此文件读入 byte 数组。

 void

seek(long pos)
          
设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。

 int

skipBytes(int n)
          
尝试跳过输入的 n 个字节以丢弃跳过的字节。

以当前指针为基点跳到下一个位置。

例子

注:这里在对文件无论是进行存还是进行取时,文件内的指针会自动移动到下一个位置。

 

可以通过seek方法调整要写入的位置,从而实现覆盖或者避免覆盖原有数据。

 

使用例子:可以实现多线程下载,分别指定线程数据写入的位置,从而实现多线程写入。

 

DataOutputStream类:

操作基本数据的流。

构造函数:

DataOutputStream(OutputStream out)
          创建一个新的数据输出流,将数据写入指定基础输出流。

 

其他方法

 void

flush()
          清空此数据输出流。

void

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

void

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

 

 

void

writeFloat(float v)
          使用 Float 类中的 floatToIntBits 方法将 float 参数转换为一个int 值,然后将该int 值以 4-byte 值形式写入基础输出流中,先写入高字节。

可以写入基本数据类型

 

例子

 

OutputStreamWriter类:

是字符流通向字节流的桥梁:可使用指定的charset 将要写入流中的字符编码成字节。

构造函数:

OutputStreamWriter(OutputStream out)
          创建使用默认字符编码的OutputStreamWriter。

 

OutputStreamWriter(OutputStream out,Charset cs)
          创建使用给定字符集的OutputStreamWriter。


其他方法

 void

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

 void

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

void

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

 void

flush()
          刷新该流的缓冲。

 

ByteArrayInputStream类:

包含一个内部缓冲区,该缓冲区包含从流中读取的字节。因此在创建之时必须要有数组对象。因为使用内部缓存,因此不需要关闭资源。

构造函数

ByteArrayInputStream(byte[] buf)
          创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。

ByteArrayInputStream(byte[] buf, int offset, int length)
          创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组。

 

常用方法

 void

close()
          关闭 ByteArrayInputStream 无效。

 int

read()
          
从此输入流中读取下一个数据字节。

 int

read(byte[] b, int off, int len)
          
将最多 len 个数据字节从此输入流读入 byte 数组。

 

 

ByteArrayOutputStream类

不用再建数组,因为其内部已经存在一个缓冲区,缓冲区会随着数据的不断写入而自动增长。可使用toByteArray()toString() 获取数据。因为使用内部缓存,因此不需要关闭资源。

构造方法:

ByteArrayOutputStream()
          创建一个新的 byte 数组输出流。

ByteArrayOutputStream(int size)
          创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量(以字节为单位)。

 

其他方法:

 int

size()
          返回缓冲区的当前大小。

 void

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

byte[]

toByteArray()
          创建一个新分配的 byte 数组。

 String

toString()
          使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串。

void

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

 void

write(int b)
          将指定的字节写入此 byte 数组输出流

 void

writeTo(OutputStream out)
          将此 byte 数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count) 调用该输出流的 write 方法效果一样。

 

例子

 

 

注:通过ByteArrayOutputStream了解CharArrayReader和StringReader;

字节、字符流总结:


字节流和字符流的区别:

1.        读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。

2.        处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。

结论:只要是处理纯文本数据,就优先考虑使用字符流。除此之外都使用字节流。

 

 

 

 

InputStream和OutputStream

 


输入字节流InputStreamIO:

1)       InputStream 是所有的输入字节流的父类,它是一个抽象类。

2)       ByteArrayInputStream、StringBufferInputStream、FileInputStream是三种基本的介质流,它们分别从Byte 数组、StringBuffer、和本地文件中读取数据。PipedInputStream 是从与其它线程共用的管道中读取数据,与Piped 相关的知识后续单独介绍。

3)       ObjectInputStream 和所有FilterInputStream的子类都是装饰流(装饰器模式的主角)。

 

输出字节流OutputStream

4)       IO 中输出字节流的继承图可见上图,可以看出:

5)       OutputStream 是所有的输出字节流的父类,它是一个抽象类。

6)       ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,

7)       ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。

Reader和Writer

Writer

1.        Writer 是所有的输出字符流的父类,它是一个抽象类。

2.        CharArrayWriter、StringWriter是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,

3.        BufferedWriter 是一个装饰器为Writer提供缓冲功能。

4.        PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。

5.        OutputStreamWriter 是OutputStream到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似,后面会有它们的对应图。

Reader

1.        Reader 是所有的输入字符流的父类,它是一个抽象类。

2.        CharReader、StringReader是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据。

3.        BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。

4.        FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。

5.        InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。后面会有Reader 与InputStream 的对应关系。

 

Java IO的一般使用原则:   

一、按数据来源(去向)分类:  

  

1、是文件: FileInputStream, FileOutputStream, FileReader, FileWriter  

  

2、是byte[]:ByteArrayInputStream, ByteArrayOutputStream  

  

3、是Char[]: CharArrayReader, CharArrayWriter  

  

4、是String: StringBufferInputStream, StringReader, StringWriter  

  

5、网络数据流:InputStream, OutputStream, Reader, Writer  

  

二、按是否格式化输出分:  

  

1、要格式化输出:PrintStream, PrintWriter  

  

三、按是否要缓冲分:  

  

1、要缓冲:BufferedInputStream, BufferedOutputStream, BufferedReader, BufferedWriter  

  

四、按数据格式分:  

  

1、二进制格式(只要不能确定是纯文本的): InputStream, OutputStream及其所有带Stream结束的子类  

  

2、纯文本格式(含纯英文与汉字或其他编码方式);Reader, Writer及其所有带Reader, Writer的子类  

  

五、按输入输出分:  

  

1、输入:Reader, InputStream类型的子类  

  

2、输出:Writer, OutputStream类型的子类  

 

编码:

常见编码表:

 

1.         ASCII:

美国标准信息交换码,7位表示

2.         IOS8859-1

拉丁码表,欧洲码表,8位表示

3.         GB312

中国中文编码,2字节

4.         GBK

GB2312升级版本,增加了中文码表,2字节代表一个字符

5.         Unicode

国际标准码,融合了多种文字,2字符一个文字

6.         UTF-8

最多用三个字节来表示一个字符:(全世界通用)。三个字节表示一个字符。

 

编码:字符串变为字节数组:String->byte[]: String.getBytes(STRING,编码格式);

解码:字节数组变为字符串:byte[]->String: new String(byte[],编码格式);

注:字符变字节就是编码,字节变字符就是解码

 

例子:

 

练习




0 0
原创粉丝点击