IO流详细学习笔记
IO流详细学习笔记
在java程序中,对于数据的输入/输出操作以"流"的方式进行;JDK提供了各种各样的"流"类,用以获取不同种类的数据;程序中通过标准的方法输入或输出数据。
输入/输入流的分类
JDK所提供的所有流类型位于包java.io内都分别继承自一下四种抽象流类型。
字符流和字节流
InputStream
和OutputStream,两个是为字节流设计的,主要用来处理字节或二进制对象,
Reader和 Writer.两个是为字符流(一个字符占两个字节)设计的,主要用来处理字符或字符串.
字符流的由来: 因为数据编码的不同,而有了对字符进行高效操作的流对象。本质其实就是基于字节流读取时,去查了指定的码表。字节流和字符流的区别:
(1)读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
(2)处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据。
(3)字节流在操作的时候本身是不会用到缓冲区的,是文件本身的直接操作的;而字符流在操作的时候下后是会用到缓冲区的,是通过缓冲区来操作文件。
结论:在开发中优先选用字节流。首先因为硬盘上的所有文件都是以字节的形式进行传输或者保存的,包括图片等内容。但是字符只是在内存中才会形成的,所以在开发中,字节流使用广泛。
节点流和处理流
节点流为可以从一个特定的数据源(节点)读写数据(如:文件、内存)。
处理流是"连接"在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
-
输入字节流InputStream
构造方法:
InputStream() 创建一个输入的stream流
方法:
available():返回stream中的可读字节数,inputstream类中的这个方法始终返回的是0,这个方法需要子类去实现。
close():关闭stream方法,这个是每次在用完流之后必须调用的方法。
read():方法是读取一个byte字节,但是返回的是int。
read(byte[]):一次性读取内容到缓冲字节数组
read(byte[],int,len):从数据流中的哪个位置offset开始读长度为len的内容到缓冲字节数组
skip(long):从stream中跳过long类型参数个位置
下面还有三个方法:
mark(int):用于标记stream的作用
markSupported():返回的是boolean类型,因为不是所有的stream都可以调用mark方法的,这个方法就是用来判断stream是否可以调用mark方法和reset方法
reset():这个方法和mark方法一起使用的,让stream回到mark的位置。
注意:
BufferedInputStream类调用mark(int readlimit)方法后读取多少字节标记才失效,是取readlimit和BufferedInputStream类的缓冲区大小两者中的最大值,而并非完全由readlimit确定。这个在JAVA文档中是没有提到的。
InputStream基类中一些特定的方法:
ByteArrayInputStream -- 把内存中的一个缓冲区作为 InputStream 使用 .
(A)ByteArrayInputStream(byte[]) 创建一个新字节数组输入流( ByteArrayInputStream ),它从指定字节数组中读取数据(使用 byte 作为其缓冲区数组)
(B)ByteArrayInputStream(byte[], int, int) 创建一个新字节数组输入流,它从指定字节数组中读取数据。
StringBufferInputStream -- 把一个 String 对象作为 InputStream .
StringBufferInputStream(String) 据指定串创建一个读取数据的输入流串。
FileInputStream -- 把一个文件作为 InputStream ,实现对文件的读取操作
(A)FileInputStream(File name) 创建一个输入文件流,从指定的 File 对象读取数据。
(B)FileInputStream(FileDescriptor) 创建一个输入文件流,从指定的文件描述器读取数据。
(C)-FileInputStream(String name) 创建一个输入文件流,从指定名称的文件读取数据。
PipedInputStream :实现了 pipe 的概念,主要在线程中使用 . 管道输入流是指一个通讯管道的接收端。
一个线程通过管道输出流发送数据,而另一个线程通过管道输入流读取数据,这样可实现两个线程间的通讯。
PipedInputStream() 创建一个管道输入流,它还未与一个管道输出流连接。
PipedInputStream(PipedOutputStream) 创建一个管道输入流 , 它已连接到一个管道输出流。
SequenceInputStream :把多个 InputStream 合并为一个 InputStream . "序列输入流"类允许应用程序把几个输入流连续地合并起来,
并且使它们像单个输入流一样出现。每个输入流依次被读取,直到到达该流的末尾。
然后"序列输入流"类关闭这个流并自动地切换到下一个输入流。
SequenceInputStream(Enumeration) 创建一个新的序列输入流,并用指定的输入流的枚举值初始化它。
SequenceInputStream(InputStream, InputStream) 创建一个新的序列输入流,初始化为首先读输入流 s1, 然后读输入流 s2 。
ObjectInputStream:用于操作Object的stream,这个在stream主要用在对象传输的过程中,其中牵涉到了序列化的知识
ObjectInputStream():实例化一个ObjectInputStream对象
ObjectInputStream(InputStream):使用一个InputStream对象来实例化一个ObjectInputStream对象,其中InputStream就是对象
FilterInputStream:是一个过滤的InputStream
FilterInputStream(InputStream):使用一个InputStream为参数实例化一个FilterInputStream,其实就是来修饰InputStream的
DataInputStream:数字格式化的stream
DataInputStream(InputStream):使用InputStream参数来初始化实例
-
输出字节流OutputStream
PrintStream:直接输出到控制台中:我们最熟悉的就是System.out他就是一个PrintStream
PrintStream(OutputStream):使用OutputStream参数来实例化PrintStream
其余与InputStream中特定方法对应对称
-
字符输入流Reader
CharArrayReader :与 ByteArrayInputStream 对应此类实现一个可用作字符输入流的字符缓冲区
StringReader : 与 StringBufferInputStream 对应其源为一个字符串的字符流。
其余与InputStream中特定方法对应
-
字符输出流Writrer
StringWriter:无与之对应的以字节为导向的 stream
OutputStreamWriter:将OutputStream转化成Writer
System.in/readLine阻塞式方法
5 数据流
DateInputStream和DateOutputStream分别继承自InputStream和OutputStream,它属于处理流,需要分别"套接在InputStream和OutputStream类型的节点流上.
DataInputStream和DataOutputStream提供了可以存取与机器无关的Java原始类型数据(如:int,double等)的方法.
6 Print流
PrintWriter和PrintStream都属于输出流,分别针对于字符和字节.
PrintWriter和PrintStream提供了重载的print
Println方法用于多种数据类型输出.
PrintWriter和PrintStrram的输出操作不会抛出异常,用户通过检测错误状态获取错误信息.
PrintWriter和PrintStream有自动flush功能.
7 Object流
把一个Object之间转换成字节流写到硬盘上或者网络上叫做序列化.
Serializable叫做可以被序列化的(标记性的接口)
如果想把某个类的对象序列化,必须实现Serializable接口
transient透明的;
transient修饰的成员变量在序列化的时候不予考虑.
externalizable接口
是Serializable的子接口,自己可以控制自己的序列化过程.(不建议使用)
Java IO 的使用原则:
一、按数据来源(去向)分类:
1 、是文件: FileInputStream, FileOutputStream, ( 字节流 )FileReader, FileWriter( 字符 )
2 、是 byte[] : ByteArrayInputStream, ByteArrayOutputStream( 字节流 )
3 、是 Char[]: CharArrayReader, CharArrayWriter( 字符流 )
4 、是 String: StringBufferInputStream, StringBufferOuputStream ( 字节流 )StringReader, StringWriter( 字符流 )
5 、网络数据流: InputStream, OutputStream,( 字节流 ) Reader, Writer( 字符流 )
二、按是否格式化输出分:
1 、要格式化输出: PrintStream, PrintWriter
三、按是否要缓冲分:
1 、要缓冲: BufferedInputStream, BufferedOutputStream,( 字节流 ) BufferedReader, BufferedWriter( 字符流 )
四、按数据格式分:
1 、二进制格式(只要不能确定是纯文本的) : InputStream, OutputStream 及其所有带 Stream 结束的子类
2 、纯文本格式(含纯英文与汉字或其他编码方式); Reader, Writer 及其所有带 Reader, Writer 的子类