成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么隨機讀寫比按順序讀寫文件就是快?

開發 前端
本文主要圍繞 RandomAccessFile 類的基本概念和常用方法,做了一次簡單的知識總結,該類是 IO 流體系中功能最豐富的文件內容訪問類,既可以讀取文件中任意位置的內容,也可以向文件任意位置寫入數據。

一、背景介紹

RandomAccessFile 類,也被稱為隨機訪問文件類。

RandomAccessFile 可以說是 Java 體系中功能最為豐富的文件操作類,相比之前介紹的通過字節流或者字符流接口方式讀寫文件,RandomAccessFile 類可以跳轉到文件的任意位置處進行讀寫數據,而無需把文件從頭讀到尾,因此讀寫性能上要快很多,但是該類僅限于操作文件,不能訪問其他的 IO 設備,如網絡、內存映像等。

所以如果需要訪問文件的部分內容,而不是把文件從頭讀到尾,使用 RandomAccessFile 將是更好的選擇。

實際上,雖然RandomAccessFile類具備隨機讀寫數據的功能,但是它既不是InputStream的子類,也不是OutputStream的子類,絕大部分的方法都是從零開始寫的,這可能是因為  RandomAccessFile 需要在文件里面前后移動,它的行為與其它的 I/O 類有著根本性的不同,所以相對比較獨立。

RandomAccessFile對象類中內置了一個位置指示器,可以指向當前讀寫處的位置,當讀寫 n 個字節后,文件指示器將指向這 n 個字節后的下一個字節處。剛打開文件時,文件指示器指向文件的開頭處,當移動文件指示器到新的位置時,隨后的讀寫將從新的位置開始,這是它與其他的文件讀寫方式最大的不同。

基本上,RandomAccessFile的工作方式是,結合DataInputStream和DataOutputStream類完成數據的讀寫,再加上自己的一些方法,比如定位用的 getFilePointer方法,在文件里移動用的seek方法,以及判斷文件大小length方法、跳過多少字節數的skipBytes方法等,來完成文件的隨機訪問和讀寫操作。

具體怎么使用呢,我們一起來看看!

二、RandomAccessFile 類基本介紹

下面先來看看一個簡單的例子。

// 獲取隨機訪問文件對象
RandomAccessFile raf = new RandomAccessFile(new File("randomFileDemo.txt"), "rw");
for (int i = 0; i < 10; i++) {
    // 寫入數據,1個int占4個字節
    raf.writeInt(i);
}
raf.close();

System.out.println("================修改前的內容===============" );
// 重新獲取隨機訪問文件對象
raf = new RandomAccessFile(new File("randomFileDemo.txt"), "rw");
for (int i = 0; i < 10; i++) {
    System.out.println("Value:" + i + ": " + raf.readInt());
}
raf.close();

// 重新獲取隨機訪問文件對象
raf = new RandomAccessFile(new File("randomFileDemo.txt"), "rw");
// 設置文件指針偏移量,從0開始,直接將文件指針移到第6個int數據后面(1個int占4個字節)
raf.seek(5 * 4);
//覆蓋第6個int數據
raf.writeInt(16);
raf.close();

System.out.println("================修改后的內容===============" );
// 重新獲取隨機訪問文件對象
raf = new RandomAccessFile(new File("randomFileDemo.txt"), "rw");
for (int i = 0; i < 10; i++) {
    System.out.println("Value:" + i + ": " + raf.readInt());
}
raf.close();

輸出結果:

================修改前的內容===============
Value:0: 0
Value:1: 1
Value:2: 2
Value:3: 3
Value:4: 4
Value:5: 5
Value:6: 6
Value:7: 7
Value:8: 8
Value:9: 9
================修改后的內容===============
Value:0: 0
Value:1: 1
Value:2: 2
Value:3: 3
Value:4: 4
Value:5: 16
Value:6: 6
Value:7: 7
Value:8: 8
Value:9: 9

RandomAccessFile類為用戶提供了兩種構造方法,具體操作方式如下:

// 第一種構造方法:指定 file 對象和讀寫模式
RandomAccessFile raf = new RandomAccessFile(File file, String mode);

// 第二種構造方法:指定 filename 路徑和讀寫模式
RandomAccessFile raf = new RandomAccessFile(String filename, String mode);

其實第二種構造方法也是new File()出來,再調用第一種構造方法,兩者都可以獲取隨機訪問文件對象。

至于mode,表示以何種方式打開文件,Java給開發者提供了四種mode值,具體解釋如下!

圖片圖片

值得注意的地方是,"rw"模式下,Java 并不強求指定的路徑下一定存在某個文件,假如文件不存在,會自動創建。

RandomAccessFile類為用戶提供的方法比較多,我們可以關注下幾個重要的方法即可,詳細方法如下圖!

圖片圖片

方法的使用,可以參考如下樣例:

RandomAccessFile file = new RandomAccessFile("file.txt", "rw");
// 以下向file文件中寫數據
file.writeInt(20);// 占4個字節
file.writeDouble(8.236598);// 占8個字節
file.writeUTF("這是一個UTF字符串");// 這個長度寫在當前文件指針的前兩個字節處,可用readShort()讀取
file.writeBoolean(true);// 占1個字節
file.writeShort(395);// 占2個字節
file.writeLong(2325451L);// 占8個字節
file.writeUTF("又是一個UTF字符串");
file.writeFloat(35.5f);// 占4個字節
file.writeChar('a');// 占2個字節

file.seek(0);// 把文件指針位置設置到文件起始處

// 以下從file文件中讀數據,要注意文件指針的位置
System.out.println("——————從file文件指定位置讀數據——————");
System.out.println(file.readInt());
System.out.println(file.readDouble());
System.out.println(file.readUTF());

file.skipBytes(3);// 將文件指針跳過3個字節,本例中即跳過了一個boolean值和short值。
System.out.println(file.readLong());

file.skipBytes(file.readShort()); // 跳過文件中“又是一個UTF字符串”所占字節,注意readShort()方法會移動文件指針,所以不用加2。
System.out.println(file.readFloat());

//以下演示文件復制操作
System.out.println("——————文件復制(從file到fileCopy)——————");
file.seek(0);
RandomAccessFile fileCopy=new RandomAccessFile("fileCopy.txt","rw");
int len=(int)file.length();//取得文件長度(字節數)
byte[] b=newbyte[len];
file.readFully(b);//讀取全部內容
fileCopy.write(b);//全部寫入目標文件
System.out.println("復制完成!");

根據以上的方法介紹,我們可以利用RandomAccessFile實現一個在任意位置插入數據的操作,具體實例如下:

public class RandomAccessFileTest1 {

    /**
     * 插入數據
     * @param skip 跳過多少過字節進行插入數據
     * @param str 要插入的字符串
     * @param fileName 文件路徑
     */
    public static void insert(long skip, String str, String fileName){
        try {
            RandomAccessFile raf = new RandomAccessFile(fileName,"rw");
            if(skip <  0 || skip > raf.length()){
                System.out.println("跳過字節數無效");
                return;
            }
            byte[] b = str.getBytes();
            raf.setLength(raf.length() + b.length);
            // 將尾部數據進行遷移
            for(long i = raf.length() - 1; i > b.length + skip - 1; i--){
                raf.seek(i - b.length);
                byte temp = raf.readByte();
                raf.seek(i);
                raf.writeByte(temp);
            }
            // 從指定的位置,開始覆寫數據
            raf.seek(skip);
            raf.write(b);
            raf.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 方法測試
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) {
        insert(0, "一起學習Java", "test.txt");
        insert(0, "Hello,", "test.txt");
    }
}

文件內容結果如下:

Hello,一起學習Java

三、RandomAccessFile 類的應用

在實際的開發過程中,RandomAccessFile 的一個重要應用場景就是網絡請求中的文件多線程下載及斷點續傳。

首先將文件分成幾塊,然后每塊用不同的線程進行下載,下面是一個利用多線程在寫文件時的例子:

public class RandomAccessFileTest2 {

    public static void main(String[] args) throws Exception {
        // 預分配文件所占的磁盤空間,磁盤中會創建一個指定大小的文件
        RandomAccessFile raf = new RandomAccessFile("test.txt", "rw");
        raf.setLength(1024*1024); // 預分配 1M 的文件空間
        raf.close();

        // 所要寫入的文件內容
        String s1 = "第一個字符串";
        String s2 = "第二個字符串";
        String s3 = "第三個字符串";
        String s4 = "第四個字符串";
        String s5 = "第五個字符串";

        // 利用多線程同時寫入一個文件
        new FileWriteThread(1024*1,s1.getBytes()).start(); // 從文件的1024字節之后開始寫入數據
        new FileWriteThread(1024*2,s2.getBytes()).start(); // 從文件的2048字節之后開始寫入數據
        new FileWriteThread(1024*3,s3.getBytes()).start(); // 從文件的3072字節之后開始寫入數據
        new FileWriteThread(1024*4,s4.getBytes()).start(); // 從文件的4096字節之后開始寫入數據
        new FileWriteThread(1024*5,s5.getBytes()).start(); // 從文件的5120字節之后開始寫入數據
    }
}

class FileWriteThread extends Thread{
    privateint skip;
    privatebyte[] content;

    public FileWriteThread(int skip,byte[] content){
        this.skip = skip;
        this.content = content;
    }

    @Override
    public void run(){
        RandomAccessFile raf = null;
        try {
            // 利用線程在文件的指定位置寫入指定數據
            raf = new RandomAccessFile("test.txt", "rw");
            raf.seek(skip);
            raf.write(content);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                raf.close();
            } catch (Exception e) {
            }
        }
    }
}

四、小結

本文主要圍繞 RandomAccessFile 類的基本概念和常用方法,做了一次簡單的知識總結,該類是 IO 流體系中功能最豐富的文件內容訪問類,既可以讀取文件中任意位置的內容,也可以向文件任意位置寫入數據。

當然 RandomAccessFile 當讀寫大文件的時候,會出現內存溢出問題,此時可以采用內存映射文件方式進行讀寫數據,關于技術會在后期的文章中進行介紹。

五、參考

1、https://www.cnblogs.com/xrq730/p/4888288.html

2、https://blog.csdn.net/akon_vm/article/details/7429245

責任編輯:武曉燕 來源: 潘志的技術筆記
相關推薦

2021-02-26 20:55:56

JavaNIO隨機

2024-05-15 09:41:22

樂觀鎖編程

2016-12-14 12:02:01

StormHadoop大數據

2017-02-14 14:20:02

StormHadoop

2022-05-07 07:35:44

工具讀寫鎖Java

2017-03-23 14:37:19

WebAssemblyasm.js編程

2024-06-11 00:01:00

并發validate場景

2021-01-21 07:53:29

面試官Promis打印e

2023-04-07 08:17:39

fasthttp場景設計HTTP

2019-10-18 09:40:19

程序員固態硬盤Linux

2020-07-17 19:31:19

PythonR編程

2021-08-05 10:00:02

Python編程語言

2024-01-01 08:10:40

Go語言map

2024-01-05 08:45:35

Go語言map

2013-05-27 10:58:10

propertiesJava語言

2021-04-02 06:35:49

Bash讀寫文件Linux

2010-07-16 09:06:57

Perl文件

2010-11-19 11:32:25

Oracle存儲過程

2018-01-09 18:46:44

數據庫架構讀寫分離

2023-10-04 18:29:24

NFS小文件業務
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99riav国产一区二区三区 | 久热免费在线 | 国产丝袜av | 日本黄色短片 | 亚洲视频在线观看 | 亚洲性人人天天夜夜摸 | 欧美成人免费 | 久久精品国产一区二区电影 | 美女黄网站视频免费 | 一区二区三区久久 | 久久99精品久久久久久国产越南 | 自拍亚洲| 能免费看的av | 欧美全黄| 精品乱码一区二区三四区 | 国产精品自产拍在线观看蜜 | 91中文字幕在线观看 | 精品在线免费观看视频 | 欧美在线一区二区三区四区 | 久久久久久久久久久久久9999 | 日本久久精品视频 | 欧美日韩在线免费 | 欧美视频精品 | 伊人青青久久 | 99在线免费观看 | 精品欧美一区二区三区久久久 | 97免费视频在线观看 | 精品国产一区二区三区日日嗨 | 欧美日韩在线视频观看 | 精品av| 国产综合第一页 | 国产超碰人人爽人人做人人爱 | 最新超碰| 国产免费视频在线 | 亚洲精品福利在线 | 国产一区欧美一区 | 国产精品国产精品 | 日韩在线 | 久久国产香蕉 | 黄色毛片在线播放 | 国产欧美日韩一区二区三区在线观看 |