详解 随机访问流

(请观看本人博文——《详解 I/O流》)

RandomAccessFile 类

(随机访问流)

概述:

RandomAccessFile 类 的实例支持对随机访问文件的读取和写入
随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。
存在指向该隐含数组的光标或索引,称为文件指针;
输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。如果随机访问文件以读取/写入模式创建,则输出操作也可用;
输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。写入隐含数组的当前末尾之后的输出操作导致该数组扩展。
该文件指针可以通过 getFilePointer 方法读取,并通过 seek 方法设置。
通常,如果此类中的所有读取例程在读取所需数量的字节之前已到达文件末尾,则抛出 EOFException(是一种 IOException)。
如果由于某些原因无法读取任何字节,而不是在读取所需数量的字节之前已到达文件末尾,则抛出 IOException,而不是 EOFException。
需要特别指出的是,如果流已被关闭,则可能抛出 IOException

相信好多通信跟我一样,看了上面那么多文字,都会有一时间读不下去的感觉。那么,本人现在来总结下 这个类的特点

特点:

特点

  1. 能读能写;
  2. 此类 不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能;
  3. 支持对随机访问文件的读取和写入;
  4. 我们可以通过getFilePointer()方法获取文件指针,并且可以通过seek()方法设置文件指针
  5. 此流可以被应用于“断点续传”。

现在,本人来展示下这个类的构造方法

构造方法

  • RandomAccessFile(File file, String mode)
    创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定
  • RandomAccessFile(String name, String mode)
    创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称

本人现在对上述的mode参数做下解释:

参数 mode

  • "r" :
    只读方式打开。
    调用结果对象的任何 write() 方法都将导致抛出 IOException
  • "rw":
    打开以便读取和写入
    如果该文件尚不存在,则尝试创建该文件
  • "rws":
    打开以便读取和写入
    对于 "rw",还要求对 文件内容 或 元数据 的每个更新都同步写入到底层存储设备
  • "rwd":
    打开以便 读取和写入
    对于 "rw",还要求对 文件内容 的每个更新都同步写入到底层存储设备

现在,本人来展示下这个类的常用API

常用API

  • void close()
    关闭此随机访问文件流并释放与该流关联的所有系统资源
  • FileChannel getChannel()
    返回与此文件关联的唯一 FileChannel 对象
  • FileDescriptor getFD()
    返回与此流关联的不透明文件描述符对象
  • long getFilePointer()
    返回此文件中的当前偏移量
  • long length()
    返回此文件的长度
  • int read()
    从此文件中读取一个数据字节
  • int read(byte[] b)
    将最多 b.length 个数据字节从此文件读入 byte 数组
  • int read(byte[] b, int off, int len)
    将最多 len 个数据字节从此文件读入 byte 数组
  • boolean readBoolean()
    从此文件读取一个 boolean
  • byte readByte()
    从此文件读取一个有符号的八位值
  • char readChar()
    从此文件读取一个字符
  • double readDouble()
    从此文件读取一个 double
  • float readFloat()
    从此文件读取一个 float
  • void readFully(byte[] b)
    将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始
  • void readFully(byte[] b, int off, int len)
    将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始
  • int readInt()
    从此文件读取一个有符号的 32 位整数。
  • String readLine()
    从此文件读取文本的下一行
  • long readLong()
    从此文件读取一个有符号的 64 位整数
  • short readShort()
    从此文件读取一个有符号的 16 位数
  • int readUnsignedByte()
    从此文件读取一个无符号的八位数
  • int readUnsignedShort()
    从此文件读取一个无符号的 16 位数
  • String readUTF()
    从此文件读取一个字符串
  • void seek(long pos)
    设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作
  • void setLength(long newLength)
    设置此文件的长度
  • int skipBytes(int n)
    尝试跳过输入的 n 个字节以丢弃跳过的字节
  • void write(byte[] b)
    将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始
  • void write(byte[] b, int off, int len)
    将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始
  • void write(int b)
    向此文件写入指定的字节
  • void writeBoolean(boolean v)
    按单字节值将 boolean 写入该文件
  • void writeByte(int v)
    按单字节值将 byte 写入该文件
  • void writeBytes(String s)
    按字节序列将该字符串写入该文件
  • void writeChar(int v)
    按双字节值将 char 写入该文件,先写高字节
  • void writeChars(String s)
    按字符序列将一个字符串写入该文件
  • void writeDouble(double v)
    使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节
  • void writeFloat(float v)
    使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节
  • void writeInt(int v)
    按四个字节将 int 写入该文件,先写高字节
  • void writeLong(long v)
    按八个字节将 long 写入该文件,先写高字节
  • void writeShort(int v)
    按两个字节将 short 写入该文件,先写高字节
  • void writeUTF(String str)
    首先,把两个字节从文件的当前文件指针写入到此文件,然后再录入字符串的相应字节信息

那么,现在,本人来通过一个例子展示下这个类的用法:

本人来展示下利用这个流来对一个mp4文件的复制:

package edu.youzg.about_io.about_file.core.Test;

import java.io.*;

public class Test {

    public static void main(String[] args) throws IOException{
        boolean end = false;
        String sourceFile = "G:\\Java\\plantsVSzombies.mp4";
        String targetFile = "copyFile.mp4";

        while (!end) {
            end = copyFile(sourceFile, targetFile);
        }
    }

    public static boolean copyFile(String sourceFile, String targetFile) throws IOException{
        RandomAccessFile reader = new RandomAccessFile(sourceFile, "rw");
        File file = new File(targetFile);
        boolean isExists = file.exists();
        RandomAccessFile writer = new RandomAccessFile(file, "rw");

        if(isExists){
            String s = new BufferedReader(new FileReader("temPos.txt")).readLine();
            int offset = Integer.parseInt(s);
            reader.seek(offset);
            writer.seek(offset);
        }else{
            reader.seek(0);
            writer.seek(0);
        }

        try {
            int len = 0;
            byte[] bytes = new byte[1024];
            int index = 1;
            while ((len = reader.read(bytes)) != -1) {
                writer.write(bytes,0,len);
            }
        }catch (Exception e){
            //一旦遇到异常,记录当前指针的位置
            long filePointer = reader.getFilePointer();
            System.out.println(filePointer);
            PrintWriter printWriter = new PrintWriter("temPos.txt");
            printWriter.println(filePointer);
            printWriter.flush();

            return false;
        }

        //释放资源
        reader.close();
        writer.close();

        return true;
    }

}

那么,本人先来展示下源文件的信息:

本人再来展示下生成的文件的信息:

通过上图,可以发现本人完成了文件的复制!
其实,上面的例子就是“断点续传”的一个基本模型。

(本人 I/O流总集篇 博文链接:https:////www.cnblogs.com/codderYouzg/p/12418404.html

原文地址:https://www.cnblogs.com/codderYouzg/p/12418680.html

时间: 2024-07-28 21:32:23

详解 随机访问流的相关文章

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

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

java 21 - 12 随机访问流(不属于IO流)

随机访问流: RandomAccessFile类不属于流,是Object类的子类. 但它融合了InputStream和OutputStream的功能. 支持对文件的随机访问读取和写入. public RandomAccessFile(String name,String mode):第一个参数是文件路径,第二个参数是操作文件的模 mode:参数指定用以打开文件的访问模式.允许的值及其含意为: 值 含意 "r" 以只读方式打开.调用结果对象的任何 write 方法都将导致抛出 IOExc

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

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

一、javaSE (二十二)登录注册IO版本案例、数据操作流、内存操作流、打印流、标准输入输出流、随机访问流、合并流、序列化流、Properties、NIO

1:登录注册Io版本案例(掌握) 要求,对着写一遍 cn.itcast.pojo User cn.itcast.dao UserDao cn.itcast.dao.impl UserDaoImp1(实现我不管) cn.itcast.game GuessNumber cn.itcast.test UserTest 2:数据操作流(操作基本类型数据的流)(理解) (1)可以操作基本类型的数据 (2)流对象名称 DataInputStream DataOutputStream 3:内存操作流(理解)

详解 内存操作流

目录 内存操作流: 字节内存操作流: 字符内存操作流: (请观看本人博文--<详解 I/O流>) 内存操作流 与之前所讲的几个流有很大的差别 容本人在这里卖个关子,相信同学们在之后的讲解中就会明白本人为何说初此话了. 那么,话不多说,开始本篇博文主题的讲解吧: 内存操作流: 概念: 此流之所以被叫做内存操作流的原因是: 此流是在内存中建立缓冲区以实现数据操作的流 正因为此原因,close()方法是无效的. 而且此流并没有将数据存入硬盘中,而是存入了内存中的一个缓冲区(即:数组)中 那么,现在,

python0.16------构造函数/析构函数/self详解/重写/访问限制/对象属性和类属性/@property/运算符重载

构造函数:__init__()引子:因为每个人一出生都是不一样的.因此,如果在Person类中直接给类元素赋值有问题,它会导致每个人的初始状态相同,这不符合大自然的逻辑.应该根据每个人的特点,给每个出生的人不一样的特性.可以通过构造函数实现这个想法.__init__()函数在使用类创建对象自动调用.注意:如果不显式写出构造函数,默认会添加一个空的构造函数. 使用构造函数:def __init__(self,name,age,height,weight):#一般定义属性在构造函数里面定义. sel

黑马程序员——————&gt; 随机访问流

RandomAccessFile是java输入/输出流体系中功能最丰富的问几十年内容访问类,它提供了众多的方法来访问文件内容,它既可以读取文件内容,也可以向文件输出数据.与普通的输入/输出流不同的是,RandomAccessFile支持“随机访问”的方式.程序可以直接跳转到文件的任意地方来读写数据. 由于RandomAccessFile可以自由访问文件的任意位置,所以如果只需要访问文件部分内容,而不是把文件从头读到尾,使用RandomAccessFile将是更好的选择. 与OutputStrea

随机访问流 RandomAccessFile

RandomAccessFile不属于流,是Object的子类 但是它融合了InputStream和OutputStream的功能,支持对文件随机读取和写入 构造方法 public RandomAccessFile(String name,String mode):第一个参数是文件路径,第二个参数是操作文件的模式 模式有4种,但是最常用的"rw",这种方法表示既可以写数据,也可以输出数据 package cn.idcast; import java.io.IOException; im

c++ vector(向量)使用方法详解(顺序访问vector的多种方式)

来源:http://www.jb51.net/article/44231.htm 作者: 字体:[增加 减小] 类型:转载 时间:2013-12-08我要评论 vector是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器,本文介绍一下使用方法 vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器.vector 是C++ STL的一个重要成员,使用它时需要包含头文件: 复制代码 代码如下: #include<vector>; 一.vector 的初始