《七》随机访问文件流

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

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

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

 

我们查看 底层源码,可以看到:

?


1

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 来看看它的用法:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

//数据输出流

        File file = new File("io"+File.separator+"a.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()); //哥

        System.out.println(dis.readUTF());  //帅锅

        dis.close();

  

 

3、通过上面的例子,我们可以看到因为 RandomAccessFile 实现了数据输入输出流,那么 RandomAccessFile 这一个类就可以完成 输入输出的功能了。

  

这里面第二个参数:String mode 有以下几种形式:(ps:为什么这里的值是固定的而不弄成枚举形式,不然很容易写错,这是因为随机访问流出现在枚举类型之前,属于Java 历史遗留问题)

  

 

 第一种:用 随机流顺序读取数据

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

public class RandomAccessFileTest {

    public static void main(String[] args) throws Exception {

        File file = new File("io"+File.separator+"a.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();

    }

 

}

  

第二种:随机读取,那么我们先介绍这两个方法

这里所说的偏移量,也就是字节数。一个文件是有N个字节数组成,那么我们可以通过设置读取或者写入的偏移量,来达到随机读取或写入的目的。

我们先看看Java 各数据类型所占字节数:

下面是 随机读取数据例子:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/**

     * 随机流读数据

     */

    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();

    }

  

 随机流复制文件:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

/**

     * 随机流复制文件

     * @param fileA

     * @param B

     * @throws Exception

     */

    private static void copyFile(File fileA,File fileB) throws Exception{

         

        RandomAccessFile srcRA = new RandomAccessFile(fileA, "rw");

        RandomAccessFile descRA = new RandomAccessFile(fileB, "rw");

         

        //向 文件 a.txt 中写入数据

        srcRA.writeByte(65);

        srcRA.writeInt(97);

        srcRA.writeUTF("帅锅");

        //获取 a.txt 文件的字节长度

        int len = (int) srcRA.length();

        srcRA.seek(0);

        System.out.println(srcRA.readByte()+srcRA.readInt()+srcRA.readUTF());

         

        //开始复制

        srcRA.seek(0);

        //定义一个数组,用来存放 a.txt 文件的数据

        byte[] buffer = new byte[len];

        //将 a.txt 文件的内容读到 buffer 中

        srcRA.readFully(buffer);

        //再将 buffer 写入到 b.txt文件中

        descRA.write(buffer);

         

        //读取 b.txt 文件中的数据

        descRA.seek(0);

        System.out.println(descRA.readByte()+descRA.readInt()+descRA.readUTF());

        //关闭流资源

        srcRA.close();

        descRA.close();

    }

  

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

时间: 2024-08-25 22:32:04

《七》随机访问文件流的相关文章

随机访问文件RandomAccessFile 与 内存映射文件MappedByteBuffer

一.RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和OutputStream类系的.实际上,除了实现DataInput和DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系

Java I/O---RandomAccessFile类(随机访问文件的读取和写入)

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

【幻化万千戏红尘】qianfengDay20-java基础学习:数据流、随机读取文件流RandomAccessFile

课程回顾: 流:转换流:字符和字节的转换对象流(Object):序列化,反序列化 打印流(Print):打印各种数据类型的数据 今日内容:数据流(Data):支持将基本数据类型写出,字节流,处理流1.DataOutputStream:数据输出字节流常用方法:writeXXX:写出基本数据类型的数据writeUTF:写出字符串2.DataInputStream:数据输入字节流常用方法:readXXX:读取基本数据类型的数据readUTF:读取字符串 随机读取文件类:拥有写出和读取基本数据类型的方法

Java核心技术:随机访问文件

import java.io.*; import java.time.LocalDate; import java.util.Scanner; public class Test { public static void main(String[] args){ // TextFileTest.test(); RandomAccessTest.test(); } } class Employee { private String name; private double salary; priv

Java基础知识强化之IO流笔记63:随机访问流RandomAccessFile

1. 随机访问流RandomAccessFile RandomAccessFile类不属于流,是Object类的子类.但它融合了InputStream和OutputStream的功能.支持对随机访问文件的读取和写入. RandomAccessFile的构造方法: 构造方法摘要 RandomAccessFile(File file, String mode)           创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定. RandomAccessFile(St

详解 随机访问流

(请观看本人博文--<详解 I/O流>) RandomAccessFile 类 (随机访问流) 概述: RandomAccessFile 类 的实例支持对随机访问文件的读取和写入. 随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组. 存在指向该隐含数组的光标或索引,称为文件指针: 输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针.如果随机访问文件以读取/写入模式创建,则输出操作也可用: 输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针.写入隐

MappedByteBuffer高速缓存文件、RandomAccessFile随机访问

说到高速缓存存储,处理读写文件,那就不得不说MappedByteBuffer. 看了好多文章以后写一下自己的总结. 在这里先介绍一下相关的类与方法. 先说一下Buffer.ByteBuffer.MappedByteBuffer这几个类之间的关系. public abstract class Buffer { // Invariants: mark <= position <= limit <= capacity private int mark = -1; private int pos

Java API —— IO流(数据操作流 &amp; 内存操作流 &amp; 打印流 &amp; 标准输入输出流 &amp; 随机访问流 &amp; 合并流 &amp; 序列化流 &amp; Properties &amp; NIO)

1.操作基本数据类型的流 1) 操作基本数据类型 · DataInputStream:数据输入流允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型.应用程序可以使用数据输出流写入稍后由数据输入流读取的数据. · DataOutputStream:数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中.然后,应用程序可以使用数据输入流将数据读入. package datastreamdemos; import java.io.*; /** * Created b

java _io_随机读取读入流RandomAccessFile

随机读取和写入流RandomAccessFile 支持读取和写入随机访问文件 RandomAccessFile raf=new RandomAccessFile(文件对象,读写模式);r只读,rw读和写 private File f; //目的地 private String dir; //所有分割后的文件存储路径 private List<String> list; //每块大小 private int blockSize; //块数 private int size; public n(F