一、IO:means input and output,通过数据流、序列化和文件系统提供系统输入和输出。Java把这些不同来源和目标的数据都统一抽象为数据流。
在Java类库中,IO部分的内容是很庞大的,Java语言的输入输出功能是十分强大而灵活的因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上的数据流,字符串流,对象流,zip文件流。
二、为什么要用IO流?
因为程序在运行时,其数据不可能在内存中长久保存,需要与硬盘交换储存,就是需要用的时候程序启动,利用IO流从硬盘中读入数据进行处理,程序退出后又调用IO流把数据存储在硬盘中,方便下次使用。
三、IO流的分类?
1、方向分:a、输入流:把外部数据读入到当前程序所在的内存中。
b、 输出流:把程序运行的内存中的数据输出到外部存储器中。
2、按流处理得数据分析:a、字节流:处理的数据单元是字节8位,由于是最小单位,适应性强,功能强大。
b、字符流:处理的数据单元是字符16位,一般用来处理文件。
3、用功能或者角色来分:a、节点流:和一个IO的物理节点关联,可以向特定IO设备(网络,硬盘)读写数据,通常被称为低级流。
b、处理流:对已经存在的流进行连接或者封装,通过封装后的流来实现数据的读写功能,处理流被称为高级流(其好处是不用管底层的流的类型及实现,直接面向流编程。
注意:
1、java的输入流主要以inputstream和reader作为基类。
2、java的输出流主要以outputstream和writer作为基类。
3、java的字节流主要以inputstream和outputstream作为基类。
4、java的字符流主要以reader和writer作为基类。
5、处理流对不同的节点流进行包装,消除各个节点流的差异化,提供更方便的方法来完成输入/输出功能。6、程序里打开的文件IO资源,不属于内存里的资源,垃圾回收器无法回收该资源,所以应该显式的关闭资源,用close方法关闭。
7、inputstream ,reader和 outputstream,writer都是抽象类,不能直接创建实例。
8、创建处理流时只需要传入一个节点流构造参数即可,这样就是包装了节点流成处理流。如下代码:
FileOutputStream fos = new FileOutputStream("cc1.txt");//创建文件输出节点流
ps= new PrintStream(fos);//把节点流包装成名字为ps的处理流。
JDK所提供的所有流类位于java.io包中,都分别继承自以下四种抽象流类:
OutputSteam:继承自OutputStream的流都是程序用于向外输出数据的,且数据单位都是字节(8位)。
Reader:继承自Reader的流都是用于向程序中输入数据的,且数据单位都是字符(16位)。
Writer:继承自Writer的流都是程序用于向外输出数据的,且数据单位都是字符(16位) 。
区别:
Reader和Writer要解决的,最主要的问题就是国际化。原先的I/O类库只支持8位的字节流,因此不可能很好地处理16位的Unicode字符流。Unicode是国际化的字符集(更何况Java内置的char就是16位的Unicode字符),这样加了Reader和Writer之后,所有的I/O就都支持Unicode了。此外新类库的性能也比旧的好。
但是,Read和Write并不是取代InputStream和OutputStream,有时,你还必须同时使用"基于byte的类"和"基于字符的类"。为此,它还提供了两个"适配器(adapter)"类。InputStreamReader负责将InputStream转化成Reader,而OutputStreamWriter则将OutputStream转化成Writer。
五、流的层次结构
定义:
(1) java将读取数据对象成为输入流,能向其写入的对象叫输出流。结构图如下:
输入流
输出流
六、java输出流体系:七、常用类方法详解:
1、InputStream类
inputstream类和outputstream类都为抽象类,不能创建对象,可以通过子类来实例化。
InputStream是输入字节数据用的类,所以InputStream类提供了3种重载的read方法.Inputstream类中的常用方法:
(1)public abstract int read( ):读取一个byte的数据,返回值是高位补0的int类型值。
(2)public int read(byte b[ ]):读取b.length个字节的数据放到b数组中。返回值是读取的字节数。该方法实际上是调用下一个方法实现的
(3) public int read(byte b[ ], int off, int len):从输入流中最多读取len个字节的数据,存放到偏移量为off的b数组中。
(4)public int available( ):返回输入流中可以读取的字节数。注意:若输入阻塞,当前线程将被挂起,如果InputStream对象调用这个方法的话,它只会返回0,这个方法必须由继承InputStream类的子类对象调用才有用,
(5 )public long skip(long n):忽略输入流中的n个字节,返回值是实际忽略的字节数, 跳过一些字节来读取
(6) public int close( ) :我们在使用完后,必须对我们打开的流进行关闭.
2、OutputStream类
OutputStream提供了3个write方法来做数据的输出,这个是和InputStream是相对应的。
1. public void write(byte b[ ]):将参数b中的字节写到输出流。
2. public void write(byte b[ ], int off, int len) :将参数b的从偏移量off开始的len个字节写到输出流。
3. public abstract void write(int b) :先将int转换为byte类型,把低字节写入到输出流中。
4. public void flush( ) : 将数据缓冲区中数据全部输出,并清空缓冲区。
5. public void close( ) : 关闭输出流并释放与流相关的系统资源。
3、FileInputStream类
FileInputStream类是InputStream类的子类,用来处理以文件作为数据输入源的数据流。使用方法:
方式1:
File fin=new File("d:/abc.txt");
FileInputStream in=new FileInputStream(fin);
方式2:
FileInputStream in=new
FileInputStream("d: /abc.txt");
方式3:
构造函数将 FileDescriptor()对象作为其参数。
FileDescriptor() fd=new FileDescriptor();
FileInputStream f2=new FileInputStream(fd)
4、FileOutputStream类
FileOutputStream类用来处理以文件作为数据输出目的数据流;一个表示文件名的字符串,也可以是File或FileDescriptor对象。
创建一个文件流对象有两种方法:
方式1:
File f=new File("d:/abc.txt");
FileOutputStream out=new FileOutputStream (f);
方式2:
FileOutputStream out=new
FileOutputStream("d:/abc.txt");
方式3:构造函数将 FileDescriptor()对象作为其参数。
FileDescriptor() fd=new FileDescriptor();
FileOutputStream f2=new FileOutputStream(fd);
方式4:构造函数将文件名作为其第一参数,将布尔值作为第二参数。
FileOutputStream f=new FileOutputStream("d:/abc.txt",true);
注意:
(1)文件中写数据时,若文件已经存在,则覆盖存在的文件;(2)的读/写操作结束时,应调用close方法关闭流。
5、File类
File类与InputStream / OutputStream类同属于一个包,它不允许访问文件内容。
File类主要用于命名文件、查询文件属性和处理文件目录。
注:有部分内容来源于网络整理