10-IO流

1. Java IO流

  • IO 流用来处理设备之间的数据传输。

  • Java 程序中,对于数据的输入/输出操作以”流(stream)"

    的方式进行。

  • java.io 包下提供了各种“流”类和接口,用以获取不同种类的数据,并通过标准的方法输入或输出数据。

java.io 包下:

  • File类:java 程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源。

    File file1 = new File(“d:\io\helloworld.txt”);
    File file2 = new File(“d:\io\io1”);
  • File 既可以表示一个文件(.doc .xls .mp3 .avi .jpg .dat),也可以表示一个文件目录!

  • File 类的对象是与平台无关的。

  • File 类针对于文件或文件目录,只能进行新建、删除、重命名、上层目录等等的操作。如果涉及到访问文件的内容,File 是无能为力的,只能使用 IO 流下提供的相应的输入输出流来实现。

  • 常把 File 类的对象作为形参传递给相应的输入输出流的构造器中!

2. IO流体系

3. IO流的划分

IO 流的分类:

  • 按操作数据单位不同分为:字节流(8bit),字符流(16bit)

  • 按数据流的流向不同分为:输入流,输出流剂

  • 按流的角色的不同分为:节点流,处理流

(抽象基类)

字节流

字符流

输入流

InputStream

Reader

输出流

OutputStream

Writer

Java 的 IO 流共涉及 40 多个类,实际上非常规则,都是从如下 4 个抽象基类派生的。由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

1) 按照流的流向的不同:输入流 输出流 (站位于程序的角度)

2) 按照流中的数据单位的不同:字节流 字符流 (纯文本文件使用字符流 ,除此之外使用字节流)

3) 按照流的角色的不同:节点流 处理流 (流直接作用于文件上是节点流(4个),除此之外都是处理流)

(1) 重点掌握

抽象基类:
InputStream
OutputStream
Reader
Writer
节点流(文件流):
FileInputStream (int read(byte[] b))
FileOutputStream (void write(b,0,len))
FileReader (int read(char[] c))
FileWriter (void write(c,0,len))
缓冲流(处理流的一种,可以提升文件操作的效率):
BufferedInputStream (int read(byte[] b))
BufferedOutputStream (flush()) (void write(b,0,len))
BufferedReader (readLine()) (int read(char[] c))或String readLine() BufferedReader (readLine()) (int read(char[] c))或String readLine()

注:

  1. 从硬盘中读入一个文件,要求此文件一定得存在。若不存在,报 FileNotFoundException 的异常

  2. 从程序中输出一个文件到硬盘,此文件可以不存在。若不存在,就创建一个实现输出。若存在,则将已存在的文件覆盖

  3. 真正开发时,就使用缓冲流来代替节点流

  4. 主要最后要关闭相应的流。先关闭输出流,再关闭输入流。将此操作放入finally

(2) 其它的流

①转换流

实现字节流与字符流之间的转换

InputStreamReader:输入时,实现字节流到字符流的转换,提高操作的效率(前提是,数据是文本文件)。解码:字节数组 --> 字符串

OutputStreamWriter:输出时,实现字符流到字节流的转换。编码: 字符串---->字节数组

例子:从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。

②标准的输入输出流

System.in: The "standard" input stream:从键盘输入数据

System.out:The "standard" output stream:从显示器输出数据

③打印流 (都是输出流)

PrintStream(处理字节)

PrintWriter(处理字符)

可以使用System.setOut(PrintStream p)重新设置一下输出的位置。

PrintStream p = new PrintStream(new FileOutputStream("hello.txt"),true);

④数据流(处理基本数据类型、String类、字节数组)

DataInputStream DataOutputStream

⑤对象流(用来处理对象的)

对象的序列化机制:

允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。

对象的序列化:

  • 对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

  • 序列化的好处在于可将任何实现了 Serializable 接口的对象转化为字节数据,使其在保存和传输时可被还原

  • 序列化是 RMI(Remote Method Invoke-远程方法调用)过程的参数和返回值都必须实现的机制,而RMI是JavaEE 的基础。

    因此序列化机制是 JavaEE 平台的基础

  • 如果需要让某个对象支持序列化机制,则必须让其类是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:

    • Serializable

    • Externalizable

ObjectInputStream(Object readObject();

ObjectOutputStream (void writeObject(Object obj)

如何创建流的对象:

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("person.txt")));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("person.txt")));

实现序列化机制的对象对应的类的要求:

  • ①要求类要实现 Serializable 接口

  • ②同样要求类的所有属性也必须实现 Serializable 接口

  • ③ 要求给类提供一个序列版本号:private static final long serialVersionUID;

  • ④属性声明为 static 或 transient 的,不可以实现序列化

⑥随机存取文件流:RandomAccessFile

(1) 构造器

  • public RandomAccessFile(File file,String mode)

  • public RandomAccessFile(String name,String mode)

(2) 创建 RandomAccessFile类实例需要指定一个 mode 参数,该参数指定 RandomAccessFile 的访问模式:

  • r:以只读方式打开

  • rw:打开以便读取和写入

  • rwd:打开以便读取和写入;同步文件内容的更新

  • rws:打开以便读取和写入;同步文件内容和元数据的更新

既可以充当一个输入流,又可以充当一个输出流:public RandomAccessFile(File file, String mode)

支持从文件的开头读取、写入。若输出的文件不存在,直接创建。若存在,则是对原有文件内容的覆盖。

支持任意位置的“插入”。