最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java RandomAccessFile的用法詳解

 更新時間:2016年06月07日 09:38:59   投稿:jingxian  
下面小編就為大家?guī)硪黄狫ava RandomAccessFile的用法詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

RandomAccessFile

RandomAccessFile是用來訪問那些保存數(shù)據(jù)記錄的文件的,你就可以用seek( )方法來訪問記錄,并進行讀寫了。這些記錄的大小不必相同;但是其大小和位置必須是可知的。但是該類僅限于操作文件。

RandomAccessFile不屬于InputStream和OutputStream類系的。實際上,除了實現(xiàn)DataInput和 DataOutput接口之外(DataInputStream和DataOutputStream也實現(xiàn)了這兩個接口),它和這兩個類系毫不相干,甚至不使用InputStream和OutputStream類中已經(jīng)存在的任何功能;它是一個完全獨立的類,所有方法(絕大多數(shù)都只屬于它自己)都是從零開始寫的。這可能是因為RandomAccessFile能在文件里面前后移動,所以它的行為與其它的I/O類有些根本性的不同??偠灾?,它是一個直接繼承Object的,獨立的類。

基本上,RandomAccessFile的工作方式是,把DataInputStream和DataOutputStream結合起來,再加上它自己的一些方法,比如定位用的getFilePointer( ),在文件里移動用的seek( ),以及判斷文件大小的length( )、skipBytes()跳過多少字節(jié)數(shù)。此外,它的構造函數(shù)還要一個表示以只讀方式("r"),還是以讀寫方式("rw")打開文件的參數(shù) (和C的fopen( )一模一樣)。它不支持只寫文件。

只有RandomAccessFile才有seek搜尋方法,而這個方法也只適用于文件。BufferedInputStream有一個mark( )方法,你可以用它來設定標記(把結果保存在一個內(nèi)部變量里),然后再調(diào)用reset( )返回這個位置,但是它的功能太弱了,而且也不怎么實用。

RandomAccessFile的絕大多數(shù)功能,但不是全部,已經(jīng)被JDK 1.4的nio的"內(nèi)存映射文件(memory-mapped files)"給取代了,你該考慮一下是不是用"內(nèi)存映射文件"來代替RandomAccessFile了。

import java.io.IOException; 
import java.io.RandomAccessFile; 
 
public class TestRandomAccessFile { 
  public static void main(String[] args) throws IOException { 
    RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw"); 
    for (int i = 0; i < 10; i++) { 
      //寫入基本類型double數(shù)據(jù) 
      rf.writeDouble(i * 1.414); 
    } 
    rf.close(); 
    rf = new RandomAccessFile("rtest.dat", "rw"); 
    //直接將文件指針移到第5個double數(shù)據(jù)后面 
    rf.seek(5 * 8); 
    //覆蓋第6個double數(shù)據(jù) 
    rf.writeDouble(47.0001); 
    rf.close(); 
    rf = new RandomAccessFile("rtest.dat", "r"); 
    for (int i = 0; i < 10; i++) { 
      System.out.println("Value " + i + ": " + rf.readDouble()); 
    } 
    rf.close(); 
  } 
}  

內(nèi)存映射文件

內(nèi)存映射文件能讓你創(chuàng)建和修改那些因為太大而無法放入內(nèi)存的文件。有了內(nèi)存映射文件,你就可以認為文件已經(jīng)全部讀進了內(nèi)存,然后把它當成一個非常大的數(shù)組來訪問。這種解決辦法能大大簡化修改文件的代碼。

fileChannel.map(FileChannel.MapMode mode, long position, long size)將此通道的文件區(qū)域直接映射到內(nèi)存中。注意,你必須指明,它是從文件的哪個位置開始映射的,映射的范圍又有多大;也就是說,它還可以映射一個大文件的某個小片斷。

MappedByteBuffer是ByteBuffer的子類,因此它具備了 ByteBuffer的所有方法,但新添了force()將緩沖區(qū)的內(nèi)容強制刷新到存儲設備中去、load()將存儲設備中的數(shù)據(jù)加載到內(nèi)存中、 isLoaded()位置內(nèi)存中的數(shù)據(jù)是否與存儲設置上同步。這里只簡單地演示了一下put()和get()方法,除此之外,你還可以使用 asCharBuffer( )之類的方法得到相應基本類型數(shù)據(jù)的緩沖視圖后,可以方便的讀寫基本類型數(shù)據(jù)。

import java.io.RandomAccessFile; 
import java.nio.MappedByteBuffer; 
import java.nio.channels.FileChannel; 
 
public class LargeMappedFiles { 
  static int length = 0x8000000; // 128 Mb 
 
  public static void main(String[] args) throws Exception { 
    // 為了以可讀可寫的方式打開文件,這里使用RandomAccessFile來創(chuàng)建文件。 
    FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel(); 
    //注意,文件通道的可讀可寫要建立在文件流本身可讀寫的基礎之上 
    MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length); 
    //寫128M的內(nèi)容 
    for (int i = 0; i < length; i++) { 
      out.put((byte) 'x'); 
    } 
    System.out.println("Finished writing"); 
    //讀取文件中間6個字節(jié)內(nèi)容 
    for (int i = length / 2; i < length / 2 + 6; i++) { 
      System.out.print((char) out.get(i)); 
    } 
    fc.close(); 
  } 
} 

盡管映射寫似乎要用到FileOutputStream,但是映射文件中的所有輸出 必須使用RandomAccessFile,但如果只需要讀時可以使用FileInputStream,寫映射文件時一定要使用隨機訪問文件,可能寫時要讀的原因吧。

該程序創(chuàng)建了一個128Mb的文件,如果一次性讀到內(nèi)存可能導致內(nèi)存溢出,但這里訪問好像只是一瞬間的事,這是因為,真正調(diào)入內(nèi)存的只是其中的一小部分,其余部分則被放在交換文件上。這樣你就可以很方便地修改超大型的文件了(最大可以到2 GB)。注意,Java是調(diào)用操作系統(tǒng)的"文件映射機制"來提升性能的。

RandomAccessFile類的應用:

/* 
 * 程序功能:演示了RandomAccessFile類的操作,同時實現(xiàn)了一個文件復制操作。 
 */ 
package com.lwj.demo; 
 
import java.io.*; 
 
public class RandomAccessFileDemo { 
 public static void main(String[] args) throws Exception { 
 RandomAccessFile file = new RandomAccessFile("file", "rw"); 
 // 以下向file文件中寫數(shù)據(jù) 
 file.writeInt(20);// 占4個字節(jié) 
 file.writeDouble(8.236598);// 占8個字節(jié) 
 file.writeUTF("這是一個UTF字符串");// 這個長度寫在當前文件指針的前兩個字節(jié)處,可用readShort()讀取 
 file.writeBoolean(true);// 占1個字節(jié) 
 file.writeShort(395);// 占2個字節(jié) 
 file.writeLong(2325451l);// 占8個字節(jié) 
 file.writeUTF("又是一個UTF字符串"); 
 file.writeFloat(35.5f);// 占4個字節(jié) 
 file.writeChar('a');// 占2個字節(jié) 
 
 file.seek(0);// 把文件指針位置設置到文件起始處 
 
 // 以下從file文件中讀數(shù)據(jù),要注意文件指針的位置 
 System.out.println("——————從file文件指定位置讀數(shù)據(jù)——————"); 
 System.out.println(file.readInt()); 
 System.out.println(file.readDouble()); 
 System.out.println(file.readUTF()); 
 
 file.skipBytes(3);// 將文件指針跳過3個字節(jié),本例中即跳過了一個boolean值和short值。 
 System.out.println(file.readLong()); 
 
 file.skipBytes(file.readShort()); // 跳過文件中“又是一個UTF字符串”所占字節(jié),注意readShort()方法會移動文件指針,所以不用加2。 
 System.out.println(file.readFloat()); 
  
 //以下演示文件復制操作 
 System.out.println("——————文件復制(從file到fileCopy)——————"); 
 file.seek(0); 
 RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw"); 
 int len=(int)file.length();//取得文件長度(字節(jié)數(shù)) 
 byte[] b=new byte[len]; 
 file.readFully(b); 
 fileCopy.write(b); 
 System.out.println("復制完成!"); 
 } 
} 

RandomAccessFile 插入寫示例:

 

/** 
 * 
 * @param skip 跳過多少過字節(jié)進行插入數(shù)據(jù) 
 * @param str 要插入的字符串 
 * @param fileName 文件路徑 
 */ 
public static void beiju(long skip, String str, String fileName){ 
  try { 
    RandomAccessFile raf = new RandomAccessFile(fileName,"rw"); 
    if(skip < 0 || skip > raf.length()){ 
      System.out.println("跳過字節(jié)數(shù)無效"); 
      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(); 
  } 
} 

利用RandomAccessFile實現(xiàn)文件的多線程下載,即多線程下載一個文件時,將文件分成幾塊,每塊用不同的線程進行下載。下面是一個利用多線程在寫文件時的例子,其中預先分配文件所需要的空間,然后在所分配的空間中進行分塊,然后寫入:

import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.RandomAccessFile; 
 
/** 
 * 測試利用多線程進行文件的寫操作 
 */ 
public class Test { 
 
  public static void main(String[] args) throws Exception { 
    // 預分配文件所占的磁盤空間,磁盤中會創(chuàng)建一個指定大小的文件 
    RandomAccessFile raf = new RandomAccessFile("D://abc.txt", "rw"); 
    raf.setLength(1024*1024); // 預分配 1M 的文件空間 
    raf.close(); 
     
    // 所要寫入的文件內(nèi)容 
    String s1 = "第一個字符串"; 
    String s2 = "第二個字符串"; 
    String s3 = "第三個字符串"; 
    String s4 = "第四個字符串"; 
    String s5 = "第五個字符串"; 
     
    // 利用多線程同時寫入一個文件 
    new FileWriteThread(1024*1,s1.getBytes()).start(); // 從文件的1024字節(jié)之后開始寫入數(shù)據(jù) 
    new FileWriteThread(1024*2,s2.getBytes()).start(); // 從文件的2048字節(jié)之后開始寫入數(shù)據(jù) 
    new FileWriteThread(1024*3,s3.getBytes()).start(); // 從文件的3072字節(jié)之后開始寫入數(shù)據(jù) 
    new FileWriteThread(1024*4,s4.getBytes()).start(); // 從文件的4096字節(jié)之后開始寫入數(shù)據(jù) 
    new FileWriteThread(1024*5,s5.getBytes()).start(); // 從文件的5120字節(jié)之后開始寫入數(shù)據(jù) 
  } 
   
  // 利用線程在文件的指定位置寫入指定數(shù)據(jù) 
  static class FileWriteThread extends Thread{ 
    private int skip; 
    private byte[] content; 
     
    public FileWriteThread(int skip,byte[] content){ 
      this.skip = skip; 
      this.content = content; 
    } 
     
    public void run(){ 
      RandomAccessFile raf = null; 
      try { 
        raf = new RandomAccessFile("D://abc.txt", "rw"); 
        raf.seek(skip); 
        raf.write(content); 
      } catch (FileNotFoundException e) { 
        e.printStackTrace(); 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
      } finally { 
        try { 
          raf.close(); 
        } catch (Exception e) { 
        } 
      } 
    } 
  } 
 
} 

以上這篇Java RandomAccessFile的用法詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java打包工具jar包詳解

    Java打包工具jar包詳解

    這篇文章主要介紹了Java打包工具jar包詳解,在本例中我們引入一個叫jaxen.jar的庫,并將所有以”org.jaxen”開頭的類重命名以”org.example.jaxen”開頭,具體實例代碼跟隨小編一起看看吧
    2021-10-10
  • Struts2訪問Servlet的三種方式

    Struts2訪問Servlet的三種方式

    這篇文章主要介紹了Struts2訪問Servlet的三種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • 利用Java查看進程內(nèi)存占用情況的實現(xiàn)方法

    利用Java查看進程內(nèi)存占用情況的實現(xiàn)方法

    在系統(tǒng)監(jiān)控和性能調(diào)優(yōu)中,了解各個進程的內(nèi)存占用情況是非常重要的一環(huán),通過查看進程內(nèi)存使用情況,開發(fā)者和運維人員可以及時發(fā)現(xiàn)異常進程、資源瓶頸和內(nèi)存泄漏問題,本項目旨在使用 Java 編寫一個簡單的程序,通過調(diào)用操作系統(tǒng)的命令來獲取系統(tǒng)中各個進程的內(nèi)存使用情況
    2025-03-03
  • java基本教程之多線程基本概念 java多線程教程

    java基本教程之多線程基本概念 java多線程教程

    多線程是Java中不可避免的一個重要主體。下面是對“JDK中新增JUC包”之前的Java多線程內(nèi)容的講解,JUC包是由Java大師Doug Lea完成并在JDK1.5版本添加到Java中的
    2014-01-01
  • Java基本概念監(jiān)視器實習原理解析

    Java基本概念監(jiān)視器實習原理解析

    這篇文章主要介紹了Java基本概念監(jiān)視器實習原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Java使用定時器編寫一個簡單的搶紅包小游戲

    Java使用定時器編寫一個簡單的搶紅包小游戲

    這篇文章主要為大家介紹了Java如何使用定時器編寫一個簡單的搶紅包小游戲,文中的示例代碼講解詳細,感興趣的小伙伴可以嘗試一下
    2022-07-07
  • Java單例模式的知識點詳解

    Java單例模式的知識點詳解

    在本篇文章里小編給大家整理的是關于Java單例模式的知識點詳解,有興趣的朋友們可以學習參考下。
    2020-02-02
  • springboot全局異常處理代碼實例

    springboot全局異常處理代碼實例

    這篇文章主要介紹了springboot全局異常處理代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 關于SpringSecurity?Context?中獲取和更改當前用戶信息的問題

    關于SpringSecurity?Context?中獲取和更改當前用戶信息的問題

    SpringSecurityContext在異步線程中無法獲取用戶信息,因其與請求線程綁定;此外,用戶信息更新后跳轉(zhuǎn)頁面時,身份會被降級為匿名,導致信息無法及時同步,本文給大家介紹SpringSecurity?Context?中獲取和更改當前用戶信息的問題,感興趣的朋友一起看看吧
    2024-09-09
  • Java中jakarta.validation數(shù)據(jù)校驗幾個主要依賴包講解

    Java中jakarta.validation數(shù)據(jù)校驗幾個主要依賴包講解

    在Java開發(fā)中,BeanValidationAPI提供了一套標準的數(shù)據(jù)驗證機制,尤其是通過JakartaBeanValidation(原HibernateValidator)實現(xiàn),文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-09-09

最新評論

社旗县| 西城区| 咸丰县| 岑巩县| 萨嘎县| 菏泽市| 五河县| 平武县| 陆川县| 竹溪县| 方正县| 镇原县| 蓝田县| 宣威市| 宁阳县| 体育| 尼玛县| 麻栗坡县| 黄陵县| 大余县| 新巴尔虎右旗| 沁阳市| 铁岭县| 喀什市| 嘉祥县| 兰考县| 大荔县| 丰台区| 清丰县| 惠来县| 喀喇沁旗| 咸丰县| 丘北县| 博野县| 克山县| 新余市| 仪陇县| 六枝特区| 唐山市| 临西县| 临城县|