java.lang.Object java.io.InputStream
所有已实现的接口: Closeable
直接已知子类:
AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream, InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream, StringBufferInputStream
此抽象类是表示字节输入流的所有类的超类。需要定义 InputStream
子类的应用程序必须总是提供返回下一个输入字节的方法。
从以下版本开始:JDK1.0
(1)字节缓存输入流: ByteArrayInputStream
ByteArrayInputStream
包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read
方法要提供的下一个字节。关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
(2)文件输入流 FileInputStream
FileInputStream
从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。FileInputStream
用于读取诸如图像数据之类的原始字节流。要读取字符流,请考虑使用 FileReader
。(博主注:此输入流是以字节的形式读取文件,对于音频、图片文件影响不大,对于字符文件可能存在编码问题,TXT纯文本这些建议用字符流输入流)
private static void read01(){
FileInputStream fis=null;
try {
fis=new FileInputStream("demo.txt");
byte[] bytes=new byte[1024]; //每次读取1024 字节
// byte[] bytes=new byte[fis.available()];
int len=0; //结尾标识
while ((len=fis.read(bytes))!=-1){ //循环读取,知道文件末尾
System.out.println(new String(bytes,0,len));//这里把字节转成string输出了
}
} catch (Exception e) {
e.printStackTrace();
}finally {//关闭流
try {
if (fis!=null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)FilterInputStream (注:个人理解这个类是一个适配器类,是为了拓展所用的,可以了解下装饰模式)
FilterInputStream
包含其他一些输入流,它将这些流用作其基本数据源,它可以直接传输数据或提供一些额外的功能。FilterInputStream
类本身只是简单地重写那些将所有请求传递给所包含输入流的 InputStream
的所有方法。FilterInputStream
的子类可进一步重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
它的子类有这么多:
BufferedInputStream, CheckedInputStream, CipherInputStream, DataInputStream, DeflaterInputStream, DigestInputStream, InflaterInputStream, LineNumberInputStream, ProgressMonitorInputStream, PushbackInputStream
比较常用的,缓冲流:BufferedInputStream在使用FileInputStream的时候,可以用它做缓存,提高读取效率。
BufferedInputStream
为另一个输入流添加一些功能,即缓冲输入以及支持 mark
和 reset
方法的能力。在创建 BufferedInputStream
时,会创建一个内部缓冲区数组。在读取或跳过流中的字节时,可根据需要从包含的输入流再次填充该内部缓冲区,一次填充多个字节。mark
操作记录输入流中的某个点,reset
操作使得在从包含的输入流中获取新字节之前,再次读取自最后一次 mark
操作后读取的所有字节。
private static void test01(){
BufferedInputStream fis=null;
BufferedOutputStream fos=null;
try {
//读取流 源
fis=new BufferedInputStream(new FileInputStream("d:/test/timo.jpg"));
//输出流
fos=new BufferedOutputStream(new FileOutputStream("d:/test/copyimg.jpg"));
int len=-1;
while ((len=fis.read())!=-1){
fos.write(len);
System.out.println("len:"+len);
}
} catch ( Exception e) {
e.printStackTrace();
}finally {
try {
if (fis!=null) fis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
if (fos!=null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行前后:
(4)对象输入流 ObjectInputStream
ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能从流读取。
(5)管道输入流 PipedInputStream
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream
对象读取,并由其他线程将其写入到相应的 PipedOutputStream
。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。 如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。
(6)合并流 SequenceInputStream
SequenceInputStream
表示其他输入流的逻辑串联。它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。(博主注:多线程下载,碎片文件合并,有用过迅雷的朋友应该知道。可以用在大文件的 切割->传输->合并,这一类的业务 )
(7)StringBufferInputStream
此类允许应用程序创建输入流,在该流中读取的字节由字符串内容提供。应用程序还可以使用 ByteArrayInputStream
从 byte 数组中读取字节。只有字符串中每个字符的低八位可以由此类使用。
java.lang.Object java.io.Reader
所有已实现的接口:Closeable, Readable
直接已知子类:BufferedReader, CharArrayReader, FilterReader, InputStreamReader, PipedReader, StringReader
用于读取字符流的抽象类。子类必须实现的方法只有 read(char[], int, int) 和 close()。但是,多数子类将重写此处定义的一些方法,以提供更高的效率和/或其他功能。
(1)缓冲的字符输入流 BufferedReader
从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。可以指定缓冲区的大小,或者可使用默认的大小。大多数情况下,默认值就足够大了。通常,Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取请求。因此,建议用 BufferedReader 包装所有其 read() 操作可能开销很高的 Reader(如 FileReader 和 InputStreamReader)。
(2)CharArrayReader 此类实现一个可用作字符输入流的字符缓冲区。
(3)java.io.FilterReader
直接已知子类:PushbackReader
用于读取已过滤的字符流的抽象类。抽象类 FilterReader
自身提供了一些将所有请求传递给所包含的流的默认方法。FilterReader
的子类应重写这些方法中的一些方法,并且还可以提供一些额外的方法和字段。
(4)InputStreamReader
InputStreamReader 是字节流通向字符流的桥梁:它使用指定的
读取字节并将其解码为字符。它使用的字符集可以由名称指定或显式给定,或者可以接受平台默认的字符集。charset
每次调用 InputStreamReader 中的一个 read() 方法都会导致从底层输入流读取一个或多个字节。要启用从字节到字符的有效转换,可以提前从底层流读取更多的字节,使其超过满足当前读取操作所需的字节。为了达到最高效率,可要考虑在 BufferedReader 内包装 InputStreamReader。
例如: BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
(5)管道 java.io.PipedReader 传送的字符输入流。
(6)java.io.StringReader 其源为一个字符串的字符流。
io包下的输入流和输出流都是成对出现的,而字节流和字符流也是有相同功能得对,所以类比这学起来比较容易。主要是区分这些流的使用场景不太好掌握,这也是io流类的难点,其实如果把每个流的功能记住了,多写写练习,就能分清了。以上部分,红色标注的类,比较重要。