A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 15127673623 中级黑马   /  2016-5-4 23:10  /  298 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

RandomAccessFile:
特点:
1:该对象即可读取,又可写入。
2:该对象中的定义了一个大型的byte数组,通过定义指针来操作这个数组。
3:可以通过该对象的getFilePointer()获取指针的位置,通过seek()方法设置指针的位置。
4:该对象操作的源和目的必须是文件。
5:其实该对象内部封装了字节读取流和字节写入流。
注意:实现随机访问,最好是数据有规律。

class RandomAccessFileDemo{
        public static void main(String[] args) throws IOException{
                write();
                read();
                randomWrite();
        }
        //随机写入数据,可以实现已有数据的修改。
        public static void randomWrite()throws IOException{
                RandomAccessFile raf = new RandomAccessFile("random.txt","rw");
                raf.seek(8*4);
                System.out.println("pos :"+raf.getFilePointer());
                raf.write("王武".getBytes());
                raf.writeInt(102);
                raf.close();
        }
        public static void read()throws IOException{
                RandomAccessFile raf = new RandomAccessFile("random.txt","r");//只读模式。
                //指定指针的位置。
                raf.seek(8*1);//实现随机读取文件中的数据。注意:数据最好有规律。
                System.out.println("pos1 :"+raf.getFilePointer());
                byte[] buf = new byte[4];
                raf.read(buf);
                String name = new String(buf);
                int age = raf.readInt();
                System.out.println(name+"::"+age);
                System.out.println("pos2 :"+raf.getFilePointer());
                raf.close();
        }
        public static void write()throws IOException{
                //rw:当这个文件不存在,会创建该文件。当文件已存在,不会创建。所以不会像输出流一样覆盖。
                RandomAccessFile raf = new RandomAccessFile("random.txt","rw");//rw读写模式
                //往文件中写入人的基本信息,姓名,年龄。
                raf.write("张三".getBytes());
                raf.writeInt(97);
                raf.close();
        }
}
------------------------------------------------------------------------------------------------
管道流:管道读取流和管道写入流可以像管道一样对接上,管道读取流就可以读取管道写入流写入的数据。
注意:需要加入多线程技术,因为单线程,先执行read,会发生死锁,因为read方法是阻塞式的,没有数据的read方法会让线程等待。
public static void main(String[] args) throws IOException{
        PipedInputStream pipin = new PipedInputStream();
        PipedOutputStream pipout = new PipedOutputStream();
        pipin.connect(pipout);
        new Thread(new Input(pipin)).start();
        new Thread(new Output(pipout)).start();
}
------------------------------------------------------------------------------------------------
对象的序列化:目的:将一个具体的对象进行持久化,写入到硬盘上。
注意:静态数据不能被序列化,因为静态数据不在堆内存中,是存储在静态方法区中。

如何将非静态的数据不进行序列化?用transient 关键字修饰此变量即可。

Serializable:用于启动对象的序列化功能,可以强制让指定类具备序列化功能,该接口中没有成员,这是一个标记接口。这个标记接口用于给序列化类提供UID。这个uid是依据类中的成员的数字签名进行运行获取的。如果不需要自动获取一个uid,可以在类中,手动指定一个名称为serialVersionUID id号。依据编译器的不同,或者对信息的高度敏感性。最好每一个序列化的类都进行手动显示的UID的指定。

import java.io.*;
class ObjectStreamDemo {
        public static void main(String[] args) throws Exception{
                writeObj();
                readObj();
        }
        public static void readObj()throws Exception{
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
                Object obj = ois.readObject();//读取一个对象。
                System.out.println(obj.toString());
        }
        public static void writeObj()throws IOException{
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
                oos.writeObject(new Person("lisi",25)); //写入一个对象。
                oos.close();
        }
}
class Person implements Serializable{
        private static final long serialVersionUID = 42L;
        private transient String name;//用transient修饰后name将不会进行序列化
        public int age;
        Person(String name,int age){
                this.name = name;
                this.age = age;
        }
        public String toString(){
                return name+"::"+age;
        }
}
-----------------------------------------------------------------------------------------------
DataOutputStream、DataInputStream:专门用于操作基本数据类型数据的对象。
DataOutputStream dos =  new DataOutputStream(new FileOutputStream("data.txt"));
        dos.writeInt(256);
        dos.close();

        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        int num = dis.readInt();
        System.out.println(num);
        dis.close();
-----------------------------------------------------------------------------------------------
ByteArrayInputStream:源:内存
ByteArrayOutputStream:目的:内存。
这两个流对象不涉及底层资源调用,操作的都是内存中数组,所以不需要关闭。
直接操作字节数组就可以了,为什么还要把数组封装到流对象中呢?因为数组本身没有方法,只有一个length属性。为了便于数组的操作,将数组进行封装,对外提供方法操作数组中的元素。

对于数组元素操作无非两种操作:设置(写)和获取(读),而这两操作正好对应流的读写操作。这两个对象就是使用了流的读写思想来操作数组。
//创建源:
        ByteArrayInputStream bis = new ByteArrayInputStream("abcdef".getBytes());
        //创建目的:
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int ch = 0;
        while((ch=bis.read())!=-1){
                bos.write(ch);
        }
        System.out.println(bos.toString());

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马