zoukankan      html  css  js  c++  java
  • Java IO详解(七)------随机访问文件流

    1、什么是 随机访问文件流 RandomAccessFile?

      该类的实例支持读取和写入随机访问文件。 随机访问文件的行为类似于存储在文件系统中的大量字节。 有一种游标,或索引到隐含的数组,称为文件指针 ; 输入操作读取从文件指针开始的字节,并使文件指针超过读取的字节。 如果在读/写模式下创建随机访问文件,则输出操作也可用; 输出操作从文件指针开始写入字节,并将文件指针提前到写入的字节。 写入隐式数组的当前端的输出操作会导致扩展数组。 文件指针可以通过读取getFilePointer方法和由设置seek方法。

      通俗来讲:我们以前讲的 IO 字节流,包装流等都是按照文件内容的顺序来读取和写入的。而这个随机访问文件流我们可以再文件的任意地方写入数据,也可以读取任意地方的字节。

    public class RandomAccessFile implements DataOutput, DataInput, Closeable {

      底层源码,实现了 DataOutput类,DataInput类。

    2、数据流:DataOutput,DataInput

      ①、DataOutput:提供将数据从任何Java基本类型转换为一系列字节,并将这些字节写入二进制流。 还有一种将String转换为modified UTF-8格式(这种格式会在写入的数据之前默认增加两个字节的长度)并编写结果字节系列的功能。

      ②、DataInput:提供从二进制流读取字节并从其中重建任何Java原语类型的数据。 还有,为了重建设施String从数据modified UTF-8格式。 

    下面我们以其典型实现:DataOutputSteam、DataInputStream 来看看它的用法:

    package streamrandom;
    
    import java.io.*;
    
    /***
     * @ClassName: DataOutputDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/11
     * @version : V1.0
     */
    public class DataOutputDemo {
        public static void main(String[] args) throws IOException {
            //RandomAccessFile
            //数据输出流
            File file = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "DataOutputDemo.txt");
            DataOutputStream dop = new DataOutputStream(new FileOutputStream(file));
    //写入三种类型的数据
            dop.write(65);
            dop.writeChar('茶');
            dop.writeUTF("雪碧");
    
            dop.close();
    
            //数据输入流
            DataInputStream dis = new DataInputStream(new FileInputStream(file));
            System.out.println(dis.read());  //65
            System.out.println(dis.readChar()); ////读取UTF
            System.out.println(dis.readUTF());  // 雪碧
    
            dis.close();
        }
    }

    3、RandomAccessFile 这一个类就可以完成 实现了数据输入输出流 的功能了。

    //创建随机存储文件流,文件属性由参数File对象指定

    public RandomAccessFile(File file, String mode)

    //创建随机存储文件流,文件名由参数name指定

    public RandomAccessFile(String name, String mode)

    “r”:以只读的方式打开,调用该对象的任何write(写)方法都会导致IOException异常
    “rw”:以读、写方式打开,支持文件的读取或写入。若文件不存在,则创建之。
    “rws”:以读、写方式打开,与“rw”不同的是,还要对文件内容的每次更新都同步更新到潜在的存储设备中去。这里的“s”表示synchronous(同步)的意思
    “rwd”:以读、写方式打开,与“rw”不同的是,还要对文件内容的每次更新都同步更新到潜在的存储设备中去。使用“rwd”模式仅要求将文件的内容更新到存储设备中,而使用“rws”模式除了更新文件的内容,还要更新文件的元数据(metadata),因此至少要求1次低级别的I/O操作

    用 随机流顺序读取数据

    package streamrandom;
    
    import java.io.File;
    import java.io.RandomAccessFile;
    
    /***
     * @ClassName: RandomAccessFileDemo
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/12
     * @version : V1.0
     */
    public class RandomAccessFileDemo {
        public static void main(String[] args) throws Exception {
            File file = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "RandomAccessFileDemo.txt");
            write(file);
            read(file);
        }
    
        /**
         * 随机流读数据
         */
        private static void read(File file) throws Exception {
            //以 r 即只读的方法读取数据
            RandomAccessFile ras = new RandomAccessFile(file, "r");
            byte b = ras.readByte();
            System.out.println(b); //65
    
            int i = ras.readInt();
            System.out.println(i); //97
    
            String str = ras.readUTF(); //可乐
            System.out.println(str);
            ras.close();
        }
    
        /**
         * 随机流写数据
         */
        private static void write(File file) throws Exception {
            //以 rw 即读写的方式写入数据
            RandomAccessFile ras = new RandomAccessFile(file, "rw");
            ras.writeByte(65);
            ras.writeInt(97);
            ras.writeUTF("可乐");
    
            ras.close();
        }
    }

    随机流读数据

    package streamrandom;
    
    import java.io.File;
    import java.io.RandomAccessFile;
    
    /***
     * @ClassName: RandomAccessFileTest
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/12
     * @version : V1.0
     */
    public class RandomAccessFileTest {
        public static void main(String[] args) throws Exception {
            File file = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "RandomAccessFileDemo.txt");
            read(file);
        }
    
        /**
         * 随机流读数据
         */
        private static void read(File file) throws Exception {
            //以 r 即只读的方法读取数据
            RandomAccessFile ras = new RandomAccessFile(file, "r");
    
            byte b = ras.readByte();
            System.out.println(b); //65
            
            //我们已经读取了一个字节的数据,那么当前偏移量为 1
            System.out.println(ras.getFilePointer());  //1
    
            //这时候我们设置 偏移量为 5,那么可以直接读取后面的字符串(前面是一个字节+一个整型数据=5个字节)
            ras.seek(5);
            
            String str = ras.readUTF(); //可乐
            System.out.println(str);
    
            //这时我们设置 偏移量为 0,那么从头开始
            ras.seek(0);
            
            System.out.println(ras.readByte()); //65
            //需要注意的是:UTF 写入的数据默认会在前面增加两个字节的长度
    
            ras.close();
        }
    
    }

     随机流复制文件:

    package streamrandom;
    
    import java.io.File;
    import java.io.RandomAccessFile;
    
    /***
     * @ClassName: RandomAccessFileCopy
     * @Description: TODO
     * @Auther: chujiu
     * @Date: 2020/6/12
     * @version : V1.0
     */
    public class RandomAccessFileCopy {
        public static void main(String[] args) throws Exception {
            File f1 = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "RandomAccessFileCopy1.txt");
            File f2 = new File("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "RandomAccessFileCopy2.txt");
            copyFile(f1, f2);
        }
    
        /**
         * 随机流复制文件
         *
         * @param fileA
         * @param
         * @throws Exception
         */
        private static void copyFile(File fileA, File fileB) throws Exception {
    
            RandomAccessFile srcRA = new RandomAccessFile(fileA, "rw");
            RandomAccessFile descRA = new RandomAccessFile(fileB, "rw");
    
            //向 文件 1.txt 中写入数据
            srcRA.writeByte(65);
            srcRA.writeInt(97);
            srcRA.writeUTF("可乐");
    
            //获取 1.txt 文件的字节长度
            int len = (int) srcRA.length();
            srcRA.seek(0);
    
    //        System.out.println(srcRA.readByte());
    //        System.out.println(srcRA.readInt());
    //        System.out.println(srcRA.readUTF());
            System.out.println(srcRA.readByte() + srcRA.readInt() + srcRA.readUTF());
    
            //开始复制
            srcRA.seek(0);
    
            //定义一个数组,用来存放 1.txt 文件的数据
            byte[] buffer = new byte[len];
    
            //将 1.txt 文件的内容读到 buffer 中
            srcRA.readFully(buffer);
    
            //再将 buffer 写入到 2.txt文件中
            descRA.write(buffer);
    
            //读取 2.txt 文件中的数据
            descRA.seek(0);
    
    //        System.out.println(descRA.readByte());
    //        System.out.println(descRA.readInt());
    //        System.out.println(descRA.readUTF());
            System.out.println(descRA.readByte() + descRA.readInt() + descRA.readUTF());
    
            //关闭流资源
            srcRA.close();
            descRA.close();
        }
    }

    ps:一般多线程下载、断点下载都可以运用此随机流

    参考文章:https://www.cnblogs.com/ysocean/tag/Java%20IO%E8%AF%A6%E8%A7%A3%E7%B3%BB%E5%88%97/

    一辈子很短,努力的做好两件事就好;第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱。
  • 相关阅读:
    springcloud2.0 添加配置中心遇到的坑
    redis 字符串和集合操作
    Linux
    流畅的python 符合python风格的对象
    流畅的python 对象引用 可变性和垃圾回收
    流畅的python 闭包
    流畅的python 使用一等函数实现设计模式
    互联网协议入门
    流畅的python 字典和集合
    流畅的python python数据模型
  • 原文地址:https://www.cnblogs.com/antao/p/13097688.html
Copyright © 2011-2022 走看看