<-----------文本I/O-------Review>
File f = new File(路径String);
-----------------PrintWriter----------------
//PrintWriter用来创建一个文件并向文本文件写入数据
PrintWriter output = new PrintWriter(f);
PrintWirter output = new PrintWriter(filename);
--------------------------------------------
-----------------Scanner--------------------
-----
Scanner 主要方法:
一般分隔符为空格,可以使用useDelimiter(String regex)设置新的分隔符模式
为了得到不同平台的行分隔符:
String lineSeparator = System.getProperty("line.separator");
-----
//Scanner用来控制台读取字符串和基本数据数值
//要从键盘读取,则用System.in
Scanner input = new Scanner(System.in);
//要从文件读取,用new File(filename)
Scanner input = new Scanner(new File(filename));
//从字符串读取,用String
Scanner input = new Scanner(String);
---------------------------------------------
<-----------字符流--------------->
Reader
Writer
<-----------二进制 I/O----------->
抽象类:
InputStream
OutputStream
文本I/O自动进行编码解码:
写入一个字符时,Java虚拟机会将统一码转化为文件指定的编码
读取一个字符时,将文件指定的编码转化为统一码
二进制I/O不用编码转化:
若使用二进制I/O将文件写入一个数值,就是将内存中的确切值复制到文件中。
例如,一个byte类的数值199在内存中是0xC7,并且在文件中显示也是0xC7,
用二进制读取一个字节时,就会从输入流中读取一个字节的数值。
对于文本编辑器或文本输出的文件,应用文本输入来读取。
二进制输出程序创建的文件,应用二进制输入来读取。
<Java类文件存储为二进制文件>
------------------------------------二进制I/O类图-------------------------------------
|---->FileInputStream(从文件读字节,可初始化Scanner)
|
| |----->DataInputStream(基本数据类型和字符串输入)
|--->InputStream ----->FilterInputStream ----
| | |----->BufferedInputStream(输入缓冲区)
| |
| |---->ObjectInputStream(基本数据类型和对象的输入)
object --->
| |---->FileOutputStream(文件写字节,可初始化PrintWriter)
| |
| | |----->DataOutputStream(基本数据类型和字符串输出)
|--->OutputStream ----->FilterOutputStream -----
| |------>BufferedOutputStream(输出缓冲区)
|
|---->ObjectOutputStream(基本数据类型和对象的输出)
--------------------------------------------------------------------------------------
<----InputStream和OutputStream---->:
从输入流读取数据的下一个字节,异常抛出 java.io.IOException 及其子类
<----FileInputStream和FileOutputStream---->:
都是为了从/向文件读/写字节。
new FileInputStream(new File(filename : String));
new FileInputStream(filename : String);
----
new FileOutputStream(file : File);
new FileOutputStream(filename : String);
new FileOutputStream(file : File,append : boolean);
new FileOutputStream(filename : String ,append : boolean);
----
FileInputStream 可以作为参数去构造一个Scanner对象;(输入程序,读出文件)
FileOutputStream 可以作为参数去构造一个PrintWriter对象;(输出程序,写入文件)
----------------------------------------------------------------------------
<----FilterInputStream 和 FilterOutputStream---->
过滤器数字流是为了某种目的过滤字节的数据流。
基本字节输入流提供的读取方法read只能用来读取字节,若要读取整数值,双精度值或字符串,
那就需要一个过滤器类来包装字节输入流。
使用过滤器类就可以读取整数值,双精度值和字符串,而不是字节和字符。
FilterInputStream和FilterOutputStream类是过滤数据的基类,需要处理数据时,就要使用
DataInputStream和DataOutputStream类来过滤字节。
<----DataInputStream 和 DataOutputStream---->
DataInputStream从数据流中读取字节,并将它们转化成正确的基本类型值或字符串。
DataOutputStream将基本的类型值或字符串转换为字节。并将字节输出到字符流。
DataInputStream 类实现DataInput接口,DataOutputStream 类实现DataOutput接口。
-----
new DataInputStream(InputStream instream)
-----
new DataOutputStream(OutputStrean outstream)
-----
<----BufferedInputStream 和 BufferedOutputStream---->
可以通过减少读写次数来提高输入和输出的速度。
BufferedInputStream和BufferedOutputStream的方法都是从InputStream和OutputStream继承下来的,
但是为存储字节添加了一个缓冲区,以提高效率。
-----
new BufferedInputStream(in : InputStream);
new BufferedInputStream(filename : String ,buffersize : int);
-----
new BufferedOutputStream(out : OutputStream);
new BufferedOutputStream(filename : String , buffersize : int);
-----
若没有指定缓冲区大小,默认为512个字节。
缓冲输入流会在每次读取调用尽可能多的将数据读入缓冲区。
相反的,只有当缓冲区已满或调用flush()方法时,缓冲输出流才会调用写入方法。
对于100MB的大文件,我们将看到使用缓冲的IO带来的实质性能的提升。
<----- ObjectInputStream 和 ObjectOutputStream ----->
DataInputStream 和 DataOutputStream 可以实现基本数据类型与字符串的输入和输出。
ObjectInputStream 和 ObjectOutputStream既可以实现基本数据类型与字符串的输入输出,
又可以实现对象的输入输出。
完全用ObjectInputStream 和 ObjectOutputStream代替DataInputStream 和 DataOutputStream.
<--------- Serializable -------->
并不是每一个对象都可以写到输出流,可以写入输出流的对象称为 “可序列化的”Serialiazable.
因为可序列化的对象为java.io.Serializable接口的实例。
java.io.Serializable是标志性接口,没有方法。
实现这个接口可以启动java的序列化机制,自动完成存储对象和数组的过程。
假设存储一个JButton对象,为了完成这个任务,需要存储该对象所有属性的当前值。
并把其所有父类的属性值都存储起来,如果这个属性是对象,则同样存储其所有属性值。
Java提供一个内在机制自动完成写对象的过程,这个过程叫做”对象序列化“。(在ObjectOutputStream中实现)
相反,读取对象就是”反序列化“。(在ObjectInputStream中实现)
----------------------------------
为了给对象序列化,需要给其加上transient.告诉java虚拟机将对象写入对象流时忽略这些数据域。
public class Foo implements java.io.Serializable{
private int v1;
private static double v2;
private transient A v3 = new A();
}
class A{ }//is not Serializable
当Foo类进行序列化时,仅需序列化变量v1,因为v2是静态变量,所以没有序列化
因为v3时transient,所以也没有序列化。若v3没有写transient,则会发生
java.io.NotSerialiazableException异常。
复制对象,如果一个对象不止一次写入对象流,不会存储对象的副本,第一次写入一个对象,
就会为它创建一个序列号。java虚拟机将对象的所有内容和序列号一起写入对象流。以后每次存储
相同的对象,都只写序列号,读出时,它们的引用相同,指的是同一个对象。
-----------------------------------
<--------- 序列化数组 --------->
只有数组内的元素是可序列化的,这个数组才是可序列化的。一个完整的数组可用writeObject方法存入
文件,随后用readObject方法恢复。
<--------- 随机访问文件 -------->
所有数据流均为只读的,只写的。
这些数据流外部是顺序文件,如果不创建新文件就不能更新它们。
经常需要修改文件或者向文件中插入新纪录,java提供了RandomAccessFile类,允许在文件内的随机位置进行读写。
RandomAccessFile 实现了DataInput和DataOutput接口。
DataInput接口定义了读取基本数据类型和字符串的方法。
DataOutput接口定义了输出基本数据类型和字符串的方法。
当创建一个RandomAccessFile数据流时,可以指定两种模式‘r’和‘rw’。
RandomAccessFile raf = new RandomAccessFile("test.dat","rw");
随机访问文件是由字节序组成的。一个称为文件指针的特殊标记定位这些字节中的某个字节的位置。文件的读写操作
就是在文件指针所指的位置上进行的。
打开文件时,文件指针置于文件的起始位置。
在文件中读取数据后,文件指针就会向前移到下一个数据项。
例如,如果使用readInt()方法读取一个int数据,Java虚拟机就会从文件指针处读取四个字节,现在,文件指针就会从
它之前的位置向前移动四个字节。
RandomAccessFile中的 seek(pos : long) : void 设置从流的起始位置到下一个read或write发生的位置之间的偏移量。
RandomAccessFile中的 skipBytes(int n) : void 跳过输入的n个字节。
File f = new File(路径String);
-----------------PrintWriter----------------
//PrintWriter用来创建一个文件并向文本文件写入数据
PrintWriter output = new PrintWriter(f);
PrintWirter output = new PrintWriter(filename);
--------------------------------------------
-----------------Scanner--------------------
-----
Scanner 主要方法:
一般分隔符为空格,可以使用useDelimiter(String regex)设置新的分隔符模式
为了得到不同平台的行分隔符:
String lineSeparator = System.getProperty("line.separator");
-----
//Scanner用来控制台读取字符串和基本数据数值
//要从键盘读取,则用System.in
Scanner input = new Scanner(System.in);
//要从文件读取,用new File(filename)
Scanner input = new Scanner(new File(filename));
//从字符串读取,用String
Scanner input = new Scanner(String);
---------------------------------------------
<-----------字符流--------------->
Reader
Writer
<-----------二进制 I/O----------->
抽象类:
InputStream
OutputStream
文本I/O自动进行编码解码:
写入一个字符时,Java虚拟机会将统一码转化为文件指定的编码
读取一个字符时,将文件指定的编码转化为统一码
二进制I/O不用编码转化:
若使用二进制I/O将文件写入一个数值,就是将内存中的确切值复制到文件中。
例如,一个byte类的数值199在内存中是0xC7,并且在文件中显示也是0xC7,
用二进制读取一个字节时,就会从输入流中读取一个字节的数值。
对于文本编辑器或文本输出的文件,应用文本输入来读取。
二进制输出程序创建的文件,应用二进制输入来读取。
<Java类文件存储为二进制文件>
------------------------------------二进制I/O类图-------------------------------------
|---->FileInputStream(从文件读字节,可初始化Scanner)
|
| |----->DataInputStream(基本数据类型和字符串输入)
|--->InputStream ----->FilterInputStream ----
| | |----->BufferedInputStream(输入缓冲区)
| |
| |---->ObjectInputStream(基本数据类型和对象的输入)
object --->
| |---->FileOutputStream(文件写字节,可初始化PrintWriter)
| |
| | |----->DataOutputStream(基本数据类型和字符串输出)
|--->OutputStream ----->FilterOutputStream -----
| |------>BufferedOutputStream(输出缓冲区)
|
|---->ObjectOutputStream(基本数据类型和对象的输出)
--------------------------------------------------------------------------------------
<----InputStream和OutputStream---->:
从输入流读取数据的下一个字节,异常抛出 java.io.IOException 及其子类
<----FileInputStream和FileOutputStream---->:
都是为了从/向文件读/写字节。
new FileInputStream(new File(filename : String));
new FileInputStream(filename : String);
----
new FileOutputStream(file : File);
new FileOutputStream(filename : String);
new FileOutputStream(file : File,append : boolean);
new FileOutputStream(filename : String ,append : boolean);
----
FileInputStream 可以作为参数去构造一个Scanner对象;(输入程序,读出文件)
FileOutputStream 可以作为参数去构造一个PrintWriter对象;(输出程序,写入文件)
----------------------------------------------------------------------------
<----FilterInputStream 和 FilterOutputStream---->
过滤器数字流是为了某种目的过滤字节的数据流。
基本字节输入流提供的读取方法read只能用来读取字节,若要读取整数值,双精度值或字符串,
那就需要一个过滤器类来包装字节输入流。
使用过滤器类就可以读取整数值,双精度值和字符串,而不是字节和字符。
FilterInputStream和FilterOutputStream类是过滤数据的基类,需要处理数据时,就要使用
DataInputStream和DataOutputStream类来过滤字节。
<----DataInputStream 和 DataOutputStream---->
DataInputStream从数据流中读取字节,并将它们转化成正确的基本类型值或字符串。
DataOutputStream将基本的类型值或字符串转换为字节。并将字节输出到字符流。
DataInputStream 类实现DataInput接口,DataOutputStream 类实现DataOutput接口。
-----
new DataInputStream(InputStream instream)
-----
new DataOutputStream(OutputStrean outstream)
-----
<----BufferedInputStream 和 BufferedOutputStream---->
可以通过减少读写次数来提高输入和输出的速度。
BufferedInputStream和BufferedOutputStream的方法都是从InputStream和OutputStream继承下来的,
但是为存储字节添加了一个缓冲区,以提高效率。
-----
new BufferedInputStream(in : InputStream);
new BufferedInputStream(filename : String ,buffersize : int);
-----
new BufferedOutputStream(out : OutputStream);
new BufferedOutputStream(filename : String , buffersize : int);
-----
若没有指定缓冲区大小,默认为512个字节。
缓冲输入流会在每次读取调用尽可能多的将数据读入缓冲区。
相反的,只有当缓冲区已满或调用flush()方法时,缓冲输出流才会调用写入方法。
对于100MB的大文件,我们将看到使用缓冲的IO带来的实质性能的提升。
<----- ObjectInputStream 和 ObjectOutputStream ----->
DataInputStream 和 DataOutputStream 可以实现基本数据类型与字符串的输入和输出。
ObjectInputStream 和 ObjectOutputStream既可以实现基本数据类型与字符串的输入输出,
又可以实现对象的输入输出。
完全用ObjectInputStream 和 ObjectOutputStream代替DataInputStream 和 DataOutputStream.
<--------- Serializable -------->
并不是每一个对象都可以写到输出流,可以写入输出流的对象称为 “可序列化的”Serialiazable.
因为可序列化的对象为java.io.Serializable接口的实例。
java.io.Serializable是标志性接口,没有方法。
实现这个接口可以启动java的序列化机制,自动完成存储对象和数组的过程。
假设存储一个JButton对象,为了完成这个任务,需要存储该对象所有属性的当前值。
并把其所有父类的属性值都存储起来,如果这个属性是对象,则同样存储其所有属性值。
Java提供一个内在机制自动完成写对象的过程,这个过程叫做”对象序列化“。(在ObjectOutputStream中实现)
相反,读取对象就是”反序列化“。(在ObjectInputStream中实现)
----------------------------------
为了给对象序列化,需要给其加上transient.告诉java虚拟机将对象写入对象流时忽略这些数据域。
public class Foo implements java.io.Serializable{
private int v1;
private static double v2;
private transient A v3 = new A();
}
class A{ }//is not Serializable
当Foo类进行序列化时,仅需序列化变量v1,因为v2是静态变量,所以没有序列化
因为v3时transient,所以也没有序列化。若v3没有写transient,则会发生
java.io.NotSerialiazableException异常。
复制对象,如果一个对象不止一次写入对象流,不会存储对象的副本,第一次写入一个对象,
就会为它创建一个序列号。java虚拟机将对象的所有内容和序列号一起写入对象流。以后每次存储
相同的对象,都只写序列号,读出时,它们的引用相同,指的是同一个对象。
-----------------------------------
<--------- 序列化数组 --------->
只有数组内的元素是可序列化的,这个数组才是可序列化的。一个完整的数组可用writeObject方法存入
文件,随后用readObject方法恢复。
<--------- 随机访问文件 -------->
所有数据流均为只读的,只写的。
这些数据流外部是顺序文件,如果不创建新文件就不能更新它们。
经常需要修改文件或者向文件中插入新纪录,java提供了RandomAccessFile类,允许在文件内的随机位置进行读写。
RandomAccessFile 实现了DataInput和DataOutput接口。
DataInput接口定义了读取基本数据类型和字符串的方法。
DataOutput接口定义了输出基本数据类型和字符串的方法。
当创建一个RandomAccessFile数据流时,可以指定两种模式‘r’和‘rw’。
RandomAccessFile raf = new RandomAccessFile("test.dat","rw");
随机访问文件是由字节序组成的。一个称为文件指针的特殊标记定位这些字节中的某个字节的位置。文件的读写操作
就是在文件指针所指的位置上进行的。
打开文件时,文件指针置于文件的起始位置。
在文件中读取数据后,文件指针就会向前移到下一个数据项。
例如,如果使用readInt()方法读取一个int数据,Java虚拟机就会从文件指针处读取四个字节,现在,文件指针就会从
它之前的位置向前移动四个字节。
RandomAccessFile中的 seek(pos : long) : void 设置从流的起始位置到下一个read或write发生的位置之间的偏移量。
RandomAccessFile中的 skipBytes(int n) : void 跳过输入的n个字节。