对象流:ObjectInputStream和OjectOutputStream
ObjectInputStream类和OjectOutputStream类创建的对象被称为对象输入流和对象输出流。对象输出流使用writeObject(Ojbect obj)方法将一个对象obj写入输出流送往目的,对象输入流使用readObject()从源中读取一个对象到程序中。
Java提供给我们的绝大数对象都是所谓序列化的,比如组件等。一个类如果实现了Serializable接口,那么这个类创建的对象就是所谓序列化对象。Serializable接口中的方法对程序是不可见的,因此实现该接口的类不需要实现额外的方法,当把一个序列化的对象写入到对象输出流时,JVM就会实现Serializable接口中的方法,接着一定格式的文本将对象写入到目的地:
import java.io.Serializable;
public class Person implements Serializable{
/**
*
*/
//设置序列号
private static final long serialVersionUID = 1L;
private String name;
//加上关键字transient后,这个成员也不能被需硫化
private transient int age;
//静态成员是不能被序列化的
static String country="cn";
public Person(String name, int age,String country) {
this.name = name;
this.age = age;
this.country=country;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return this.name+"...."+this.age+"...."+this.country;
}
}
<pre>
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ObjectStreamDemo {
public static void main(String[] args) throws Exception{
// writeObj();
readObj();
}
public static void writeObj() throws IOException, IOException{
//创建对象输出流
ObjectOutputStream oos=
new ObjectOutputStream(new FileOutputStream("D:\\a\\oboutstrem.txt"));
//写入Person对象
oos.writeObject(new Person("lisi",39,"aaa"));
//关闭流
oos.close();
}
public static void readObj() throws Exception
{
//创建对象写入流
ObjectInputStream ois=
new ObjectInputStream(new FileInputStream("D:\\a\\oboutstrem.txt"));
//读取一个对象,并转换成person类型
Person p=(Person) ois.readObject();
ois.close();
System.out.println(p);
}
}
管道流:PipedInputStream管道输入流和PipedOutputStream管道输出流
RandomAccessFile
该类不算是IO体系中的子类
而是直接继承自Object类。但是他是IO包中的成员。因为它具备读写功能。内部封装了一个数组。而且通过指针对数组的元素进行排序。可以通过getFilePointer获取指针位置。同时可以通过seek改变指针的位置。其实完成读写的原理就是内部封装了字节输入流和输出流。通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:r,rw,rws,rwd 如果模式为r,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会抛出异常。如果模式为rw,操作的文件不存在,会自动创建。如果存在则不会覆盖
管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从PipedInputStream
对象读取,并由其他线程将其写入到相应的PipedOutputStream
。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道以损坏。
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
public class PipedStreamDemo {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
//创建管道输入流与管道输出流
PipedInputStream in=new PipedInputStream();
PipedOutputStream out=new PipedOutputStream();
//管道输入流连接到管道输出流
in.connect(out);
Read r=new Read(in);
Writer w=new Writer(out);
new Thread(r).start();
new Thread(w).start();
}
}
class Read implements Runnable{
private PipedInputStream in;
public Read(PipedInputStream in) {
// TODO Auto-generated constructor stub
this.in=in;
}
@Override
public void run() {
// TODO Auto-generated method stub
try{
//定义byte数组
byte[] buf=new byte[1024];
//管道输入流读取
int len=in.read(buf);
//把字符数组转化成字符串
String s=new String(buf,0,len);
System.out.println(s);
//关闭流对象
in.close();
}
catch(Exception e){
throw new RuntimeException("失败");
}
}
}
class Writer implements Runnable
{
private PipedOutputStream out;
public Writer(PipedOutputStream out) {
// TODO Auto-generated constructor stub
this.out=out;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
out.write("piped lai la:".getBytes());
out.close();
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException("失败");
}
}
}
随机读写流:RandomAccessFile类
RandomAccessFile
该类不算是IO体系中的子类
而是直接继承自Object类。但是他是IO包中的成员。因为它具备读写功能。内部封装了一个数组。而且通过指针对数组的元素进行排序。可以通过getFilePointer获取指针位置。同时可以通过seek改变指针的位置。其实完成读写的原理就是内部封装了字节输入流和输出流。通过构造函数可以看出,该类只能操作文件。而且操作文件还有模式:r,rw,rws,rwd 如果模式为r,不会创建文件,会去读取一个已存在的文件,如果该文件不存在,则会抛出异常。如果模式为rw,操作的文件不存在,会自动创建。如果存在则不会覆盖
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
public class RandomAccessFileDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// writeFile();
// readFile();
writeFile_2();
}
public static void writeFile() throws IOException{
RandomAccessFile raf=new RandomAccessFile("D:\\a\\ran.txt", "rw");
raf.write("你好".getBytes());
raf.writeInt(97);
raf.write("hello".getBytes());
raf.writeInt(98);
raf.close();
}
public static void readFile() throws IOException{
RandomAccessFile raf=new RandomAccessFile("D:\\a\\ran.txt", "r");
//调整对象中的指针,可以前后跳
// raf.seek(8);
//跳过指定的字节数,可以往回跳
raf.skipBytes(8);
byte b[]=new byte[5];
raf.read(b);
System.out.println(new String(b));
System.out.println(raf.readInt());
raf.close();
}
public static void writeFile_2() throws IOException{
RandomAccessFile raf=new RandomAccessFile("D:\\a\\ran.txt", "rw");
raf.seek(8*0);
raf.write("周七".getBytes());
raf.close();
}
}
数据流:DataInputStream数据输入流类和DataOutputStream数据输出流类
数据输入流和数据输出流类创建的对象称为数据输入流和数据输出流。
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*DataInputStream与DataOutputStream
操作基本数据类型的数据的流对象。*/
public class DataStreamDemo {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
// writeData();
// readData();
// writeUTF();
readUTF();
}
public static void writeData() throws IOException{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("D:\\a\\data.txt"));
//写入一个int值
dos.writeInt(123);
//写入一个boolean值
dos.writeBoolean(true);
//写入一个long值
dos.writeLong(1235456L);
dos.close();
}
public static void readData() throws IOException{
DataInputStream dis=new DataInputStream(new FileInputStream("D:\\a\\data.txt"));
//读写时,要按照写入的顺序读取相应的值
int num=dis.readInt();
boolean b=dis.readBoolean();
long l=dis.readLong();
System.out.println(num+"..."+b+"..."+l);
dis.close();
}
public static void writeUTF() throws IOException{
DataOutputStream dos=new DataOutputStream(new FileOutputStream("D:\\a\\utf.txt"));
//按utf-8修改版编码写入数据
dos.writeUTF("你好啊");
dos.close();
}
public static void readUTF() throws IOException{
DataInputStream dis=new DataInputStream(new FileInputStream("D:\\a\\utf.txt"));
//按utf-8修改版编码读出数据
System.out.println(dis.readUTF());
dis.close();
}
}
数组流:ByteArrayInputStream字节输入流类和ByteArrayOutputStream字节输出流
用于操作字节数组的流对象。ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组。ByteArrayOutputStream:在构造的时候,不用定义数据目的。因为该对象中在内部已经封装了可变长度的字节数组。这就是数据目的的。因为这两个流对象都操作的是数组,并没有使用系统资源。所以,不用进行close关闭。这是用流的思想操作数组
用于操作字节数组的流对象。ByteArrayInputStream:在构造的时候,需要接受数据源,而且数据源是一个字节数组。ByteArrayOutputStream:在构造的时候,不用定义数据目的。因为该对象中在内部已经封装了可变长度的字节数组。这就是数据目的的。因为这两个流对象都操作的是数组,并没有使用系统资源。所以,不用进行close关闭。这是用流的思想操作数组
字符串流:的StringReader和StringWriter中
数组流举例:
数组流举例:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class ByteArrayStreamDemo {
public static void main(String[] args) throws IOException{
// TODO Auto-generated method stub
//数据源
ByteArrayInputStream bis=new ByteArrayInputStream("ABCDEFG".getBytes());
//数据目的
ByteArrayOutputStream bos=new ByteArrayOutputStream();
int by=0;
while((by=bis.read())!=-1)
{
bos.write(by);
}
System.out.println(bos.size());
System.out.println(bos.toString());
//把输出流的东西写入到文件中
bos.writeTo(new FileOutputStream("D:\\a\\byte.txt"));
}
}