您的位置:首页 > 职场人生

黑马程序员--IO流(操作对象、管道流、RandomAccessFile)

2015-09-05 17:22 489 查看
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-

操作对象

ObjectOutputStream 和 ObjectInputStream

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储。如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。

只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。

writeObject 方法用于将对象写入流中。所有对象(包括 String 和数组)都可以通过 writeObject 写入。可将多个对象或基元写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。

ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。

package third;

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) {
try {
writeObj();
readObj();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void readObj()throws IOException, ClassNotFoundException {
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("E:\\obj.txt"));
Person p=(Person) ois.readObject();
System.out.println(p);
ois.close();
}
public static void writeObj()throws IOException {
ObjectOutputStream oos=
new ObjectOutputStream(new FileOutputStream("E:\\obj.txt"));
oos.writeObject(new Person("zhangsan", 23));
oos.close();
}
}


管道流(PipedInputStream 和 PipedOutputStream)

管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的所有数据字节。通常,数据由某个线程从 PipedInputStream 对象读取,并由其他线程将其写入到相应的 PipedOutputStream。不建议对这两个对象尝试使用单个线程,因为这样可能死锁线程。管道输入流包含一个缓冲区,可在缓冲区限定的范围内将读操作和写操作分离开。如果向连接管道输出流提供数据字节的线程不再存在,则认为该管道已损坏。

package third;

import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

public class PipeStreamDemo {
public static void main(String[] args) {
PipedOutputStream out =new PipedOutputStream();
PipedInputStream in=null;
try {
in = new PipedInputStream(out);
} catch (IOException e) {
e.printStackTrace();
}

Read r=new Read(in);
Write w=new Write(out);
new Thread(r).start();
new Thread(w).start();
}
}
class Read implements Runnable{
private PipedInputStream in;
public Read(PipedInputStream in) {
this.in=in;
}
@Override
public void run() {
byte[]b=new byte[1024];
try {
System.out.println("读取前,。线程堵塞。");
int len=in.read(b);
System.out.println("读取后。。阻塞结束。");
String s=new String(b, 0, len);
System.out.println(s);

} catch (IOException e) {
e.printStackTrace();
}finally {
if (in!=null)
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}
class Write implements Runnable{
private PipedOutputStream out;
public Write(PipedOutputStream out) {
this.out=out;
}
@Override
public void run() {
try {
System.out.println("正在写入数据,请稍后。。。");
Thread.sleep(6000);
out.write("piped come on".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(out!=null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}


RandomAccessFile

此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。

通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。需要特别指出的是,如果流已被关闭,则可能抛出 IOException。

RandomAccessFile不算是IO体系中的子类,而是直接继承Object。但是它是IO包中的成员,因为它具备读写功能,它内部封装了一个数组,而且通过指针对数组进行操作,可以通过getFilePointer获取指针的位置,也可以通过seek改变指针的位置

RandomAccessFile完成读写的原理是其内部封装了字节流

通过构造函数我们可以看出,该类只能操作文件,而且操作文件还有模式(r,rw等)

r模式:如果文件不存在会报错

rw模式:如果文件不存在会创建,如果已经存在,不会覆盖

package third;

import java.io.IOException;
import java.io.RandomAccessFile;

public class RandomAccessFileDemo {
public static void main(String[] args) {
try {
writeFile();
readFile();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeFile() throws IOException {
RandomAccessFile raf=new RandomAccessFile("E:\\raf.txt", "rw");
raf.write("李四".getBytes());
raf.writeInt(99);
raf.write("王五".getBytes());
raf.writeInt(100);
raf.seek(8*4);
raf.write("张三".getBytes());
raf.writeInt(103);
raf.close();
}
public static void readFile() throws IOException {
RandomAccessFile raf=new RandomAccessFile("E:\\raf.txt", "r");
raf.seek(8*1);//下面去了第二个人的,指针移动到第八位,
//当然也可以用skipByte(8),往后跳过多少
byte[]b=new byte[4];
raf.read(b);
System.out.println(new String(b));
System.out.println(raf.readInt());
raf.close();
}
}


注:RandomAccessFile可以对文件的任意位置进行操作,这就意味着我们可以使用多线程同时操作一个文件,像可以多线程下载等
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java