IO流中,除了之前总结的输出,输入流,还有一些其他流,这些流在日常的开发中需要我们熟知的.
1. 操作基本数据类型的流 数据输出流允许应用程序以适当方式将基本Java数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入.
DateInputStream 使用构造方法传递字节输入流,readInt方法读取4个字节的基本数据类型,结尾不返回-1,将抛 出EOFException异常.
DateOutputStream 使用构造方法出啊你的字节输出流,writeInt(int)写4个字节的基本数据类型int,其中负数为 有效基本数据类型.
案例:
public class DataStreamDemo {
public static void main(String[] args) throws Exception {
readWhile();
//write();
}
// 定义方法,循环读取基本类型,包装,基本类型有规律的
public static void readWhile() throws Exception {
// 创建基本数据类型输入流,传递字节输入流,包装文件
DataInputStream dis = new DataInputStream(new FileInputStream(
"c:\\data.txt"));
//循环读取基本类型,不能依赖-1停止循环,利用异常
while(true){
try{
int x = dis.readInt();
System.out.println(x);
}catch(IOException e){
break;
}
}
/*int x = dis.readInt();
System.out.println(x);
x = dis.readInt();
System.out.println(x);
x = dis.readInt();
System.out.println(x);
x = dis.readInt();
System.out.println(x);*/
dis.close();
}
// 定义方法,读取文件中基本数据类型,int 4个字节
public static void read() throws Exception {
// 创建基本数据类型输入流,传递字节输入流,包装文件
DataInputStream dis = new DataInputStream(new FileInputStream(
"c:\\data.txt"));
// 调用方法 readInt读取基本类型
int x = dis.readInt();
System.out.println(x);
// 调用方法readBoolean读取布尔值
boolean b = dis.readBoolean();
System.out.println(b);
dis.close();
}
// 定义方法,将基本类型int,4个字节写入到文件中
public static void write() throws Exception {
// 创建基本数据类型输出流,传递字节输出流,包装文件
DataOutputStream dos = new DataOutputStream(new FileOutputStream(
"c:\\data.txt"));
// 写一个基本数据类型 writeInt
dos.writeInt(97);
dos.writeInt(98);
dos.writeInt(99);
// dos.writeBoolean(false);
dos.close();
}
}
2. 内存操作流 即内存流,读写都在内存中进行.内存流不占用操作系统资源,不会抛出异常,关闭无效.
操作字节数组: ByteArrayInputStream 和 ByteArrayOutputStream
操作字符数组: CharArrayReader 和 CharArrayWriter
操作字符串: StringReader 和 StringWriter
3. 打印流 主要是为其他输出流添加打印功能.特点是:打印流不操作数据源,只操作数据的目的,永远不会抛出IO异常.
PrintStream 字节输出流 继承OutputStream
PrintWriter 字符输出流 继承Writer
两者的区别在于,两个打印流支持的数据目的不同.PrintStream的构造方法接受File数据目的,OutputStream 字节输出流的目的,以及String 文件名目的.PrintWriter的构造方法接受数据目的包含PrintStream接受的数据 目的,除此之外,它还接受Writer字符输出流目的.
两者的输出方法完全一样,都是 print println
如果在服务器端使用打印流,可将数据打印到客户端的浏览器上.
注意:打印流可以开启自动刷新,而启动自动刷新,必须调用println,print,format三个方法才有效
public static void method_1()throws Exception{
PrintWriter pw = new PrintWriter(new FileOutputStream("c:\\print.txt"),true);
pw.println("你好") ;
pw.println(true) ;
pw.println(100) ;
pw.close();
}
4. 标准输入输出流 System类中的字段:int,out.各代表系统标准的输入和输出设备.System.in的类型是InputStream System.out的类型是PrintStream,是OutputStream的子类FileOutputStream的子类.
5. 随机访问流 RandomAccessFile类不属于流,它是Objecct类的子类.但它融合了InputStream和OutputStream的功能.支持对随机访问文件的读取和写入.RandomAccessFile 隐含大型字节数组,文件都是由字节组成,文件以二进制,放在自己的数组中.大型字节数组,指针,索引,文件指针,操作文件指针,达到随机读写的目的.
使用seek(long l)设置大型数组指针.
构造器:RandomAccessFile(File file, String mode) //传递File对象,包装文件
RandomAccessFile(String name, String mode) //传递字符串文件名
访问模式: "r" 以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。
"rw" 打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws" 打开以便读取和写入,相对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到 底层存储设备。
"rwd" 打开以便读取和写入,相对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设 备。
一般使用rw模式。
6. 序列化流 对象序列化是将对象状态转换为可保持或传输的过程。一般的格式是与平台无关的二进制流,可以将这种二进制流持久保存在磁盘上,也可以通过网络将这种二进制流传输到另一个网络结点。
对象反序列化,是指把这种二进制流数据还原成对象。
序列化流 ObjectOutputStream
反序列化流 ObjectInputStream
实现对象的序列化,需有流的支持.需要实现Serializable接口.开启序列化功能.此接口中没有抽象方法,实现后,不需要重写任何方法.因此,凡是没有抽象方法的接口,即为标记型接口.静态成员变量属于类,不许与对象,因此不能序列化.当transient修饰成员变量是,可以阻止序列化.当修改源代码后,必须保证修改前后的文件序列号一样,因此,我们需要给类自己定义一个序列号,保证对象的序列化.
//这里就不给定义Person类的代码了
import java.io.*;
public class ObjectStreamDemo {
public static void main(String[] args)throws IOException,ClassNotFoundException {
// writeObj();
readObject();
}
/*
ObjectInputStream 实现对象的反序列化
readObject抛出类找不到异常,实现反序列化,必须有class文件
*/
public static void readObject()throws IOException,ClassNotFoundException{
//创建读取流对象,传递字节输入流,封装文件
ObjectInputStream ois =
new ObjectInputStream(new FileInputStream("c:\\person.txt"));
//读取对象的方法 readObject
Object o = ois.readObject();
System.out.println(o);
ois.close();
}
/*
* ObjectOutputStream实现对象序列化
*/
public static void writeObj()throws IOException{
//创建写对象流,传递字节输出流,包装一个文件
ObjectOutputStream oos = new
ObjectOutputStream(new FileOutputStream("c:\\person.txt"));
Person p = new Person("lisi",20);
//调用写对象流的方法 writeObject
oos.writeObject(p);
oos.close();
}
}
7. Propertise集合
我们还记得,在Map接口的实现类中有一个Hashtable,虽然它被HashMap在功能上取代了,但是它的子类Properties依然活跃着,最主要的是它可以结合IO使用,Properties是一个线程安全的集合,泛型固定为String.
Properties 存储和取出完全适用于Map集合(keySet entrySet put )
setProperty(String key,String value) 存储键值对到集合
String getProperty(String key)根据键获取值
Properties方法load(传递字节或者字符 输入流)将流中读取的键值对,存储到集合.文件存储键值对 key=value
Properties类方法 store(传递字节或者字符输出流,String comments)
import java.io.*;
import java.util.*;
public class PropertiesDemo {
public static void main(String[] args) throws Exception{
method_1();
}
/*
* 将集合中的键值对,存储回文件中
*/
public static void method_1()throws Exception{
FileInputStream fis = new FileInputStream("c:\\pro.txt");
Properties pro = new Properties();
pro.load(fis);
fis.close();
System.out.println(pro);
//修改集合中键值对 存储方法存储重复键
pro.setProperty("name", "wangwu");
System.out.println(pro);
//字节输出流,将集合中的键值对,写回文件
FileOutputStream fos = new FileOutputStream("c:\\pro.txt");
//集合方法store
pro.store(fos, "");
fos.close();
}
/*
* 集合方法load 从IO中加载键值对存储到集合
*/
public static void method()throws Exception{
FileInputStream fis = new FileInputStream("c:\\pro.txt");
Properties pro = new Properties();
pro.load(fis);
fis.close();
System.out.println(pro);
String value = pro.getProperty("name");
System.out.println(value);
pro.setProperty("name", "wangwu");
System.out.println(pro);
}
}