亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2614 | 回復(fù): 0
打印 上一主題 下一主題

[Android] Java RandomAccessFile用法 [復(fù)制鏈接]

論壇徽章:
80
20周年集字徽章-慶
日期:2020-10-28 14:09:1215-16賽季CBA聯(lián)賽之北京
日期:2020-10-28 13:32:5315-16賽季CBA聯(lián)賽之北控
日期:2020-10-28 13:32:4815-16賽季CBA聯(lián)賽之天津
日期:2020-10-28 13:13:35黑曼巴
日期:2020-10-28 12:29:1520周年集字徽章-周	
日期:2020-10-31 15:10:0720周年集字徽章-20	
日期:2020-10-31 15:10:07ChinaUnix元老
日期:2015-09-29 11:56:3020周年集字徽章-年
日期:2020-10-28 14:14:56
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-10-21 16:12 |只看該作者 |倒序?yàn)g覽
本帖最后由 baopbird2005 于 2015-10-21 16:14 編輯

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

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

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

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

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

  3. public class TestRandomAccessFile {
  4.         public static void main(String[] args) throws IOException {
  5.                 RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw");
  6.                 for (int i = 0; i < 10; i++) {
  7.                         //寫入基本類型double數(shù)據(jù)
  8.                         rf.writeDouble(i * 1.414);
  9.                 }
  10.                 rf.close();
  11.                 rf = new RandomAccessFile("rtest.dat", "rw");
  12.                 //直接將文件指針移到第5個(gè)double數(shù)據(jù)后面
  13.                 rf.seek(5 * 8);
  14.                 //覆蓋第6個(gè)double數(shù)據(jù)
  15.                 rf.writeDouble(47.0001);
  16.                 rf.close();
  17.                 rf = new RandomAccessFile("rtest.dat", "r");
  18.                 for (int i = 0; i < 10; i++) {
  19.                         System.out.println("Value " + i + ": " + rf.readDouble());
  20.                 }
  21.                 rf.close();
  22.         }
  23. }
復(fù)制代碼
內(nèi)存映射文件

內(nèi)存映射文件能讓你創(chuàng)建和修改那些因?yàn)樘蠖鵁o法放入內(nèi)存的文件。有了內(nèi)存映射文件,你就可以認(rèn)為文件已經(jīng)全部讀進(jìn)了內(nèi)存,然后把它當(dāng)成一個(gè)非常大的數(shù)組來訪問。這種解決辦法能大大簡(jiǎn)化修改文件的代碼。
fileChannel.map(FileChannel.MapMode mode, long position, long size)將此通道的文件區(qū)域直接映射到內(nèi)存中。注意,你必須指明,它是從文件的哪個(gè)位置開始映射的,映射的范圍又有多大;也就是說,它還可以映射一個(gè)大文件的某個(gè)小片斷。

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

  4. public class LargeMappedFiles {
  5.         static int length = 0x8000000; // 128 Mb

  6.         public static void main(String[] args) throws Exception {
  7.                 // 為了以可讀可寫的方式打開文件,這里使用RandomAccessFile來創(chuàng)建文件。
  8.                 FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel();
  9.                 //注意,文件通道的可讀可寫要建立在文件流本身可讀寫的基礎(chǔ)之上
  10.                 MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length);
  11.                 //寫128M的內(nèi)容
  12.                 for (int i = 0; i < length; i++) {
  13.                         out.put((byte) 'x');
  14.                 }
  15.                 System.out.println("Finished writing");
  16.                 //讀取文件中間6個(gè)字節(jié)內(nèi)容
  17.                 for (int i = length / 2; i < length / 2 + 6; i++) {
  18.                         System.out.print((char) out.get(i));
  19.                 }
  20.                 fc.close();
  21.         }
  22. }
復(fù)制代碼
盡管映射寫似乎要用到FileOutputStream,但是映射文件中的所有輸出 必須使用RandomAccessFile,但如果只需要讀時(shí)可以使用FileInputStream,寫映射文件時(shí)一定要使用隨機(jī)訪問文件,可能寫時(shí)要讀的原因吧。

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

RandomAccessFile類的應(yīng)用:
  1. /*
  2. * 程序功能:演示了RandomAccessFile類的操作,同時(shí)實(shí)現(xiàn)了一個(gè)文件復(fù)制操作。
  3. */
  4. package com.lwj.demo;

  5. import java.io.*;

  6. public class RandomAccessFileDemo {
  7. public static void main(String[] args) throws Exception {
  8.   RandomAccessFile file = new RandomAccessFile("file", "rw");
  9.   // 以下向file文件中寫數(shù)據(jù)
  10.   file.writeInt(20);// 占4個(gè)字節(jié)
  11.   file.writeDouble(8.236598);// 占8個(gè)字節(jié)
  12.   file.writeUTF("這是一個(gè)UTF字符串");// 這個(gè)長(zhǎng)度寫在當(dāng)前文件指針的前兩個(gè)字節(jié)處,可用readShort()讀取
  13.   file.writeBoolean(true);// 占1個(gè)字節(jié)
  14.   file.writeShort(395);// 占2個(gè)字節(jié)
  15.   file.writeLong(2325451l);// 占8個(gè)字節(jié)
  16.   file.writeUTF("又是一個(gè)UTF字符串");
  17.   file.writeFloat(35.5f);// 占4個(gè)字節(jié)
  18.   file.writeChar('a');// 占2個(gè)字節(jié)

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

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

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

  27.   file.skipBytes(file.readShort()); // 跳過文件中“又是一個(gè)UTF字符串”所占字節(jié),注意readShort()方法會(huì)移動(dòng)文件指針,所以不用加2。
  28.   System.out.println(file.readFloat());
  29.   
  30.   //以下演示文件復(fù)制操作
  31.   System.out.println("——————文件復(fù)制(從file到fileCopy)——————");
  32.   file.seek(0);
  33.   RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw");
  34.   int len=(int)file.length();//取得文件長(zhǎng)度(字節(jié)數(shù))
  35.   byte[] b=new byte[len];
  36.   file.readFully(b);
  37.   fileCopy.write(b);
  38.   System.out.println("復(fù)制完成!");
  39. }
  40. }
復(fù)制代碼
RandomAccessFile 插入寫示例:
  1. /**
  2. *
  3. * @param skip 跳過多少過字節(jié)進(jìn)行插入數(shù)據(jù)
  4. * @param str 要插入的字符串
  5. * @param fileName 文件路徑
  6. */
  7. public static void beiju(long skip, String str, String fileName){
  8.         try {
  9.                 RandomAccessFile raf = new RandomAccessFile(fileName,"rw");
  10.                 if(skip <  0 || skip > raf.length()){
  11.                         System.out.println("跳過字節(jié)數(shù)無效");
  12.                         return;
  13.                 }
  14.                 byte[] b = str.getBytes();
  15.                 raf.setLength(raf.length() + b.length);
  16.                 for(long i = raf.length() - 1; i > b.length + skip - 1; i--){
  17.                         raf.seek(i - b.length);
  18.                         byte temp = raf.readByte();
  19.                         raf.seek(i);
  20.                         raf.writeByte(temp);
  21.                 }
  22.                 raf.seek(skip);
  23.                 raf.write(b);
  24.                 raf.close();
  25.         } catch (Exception e) {
  26.                 e.printStackTrace();
  27.         }
  28. }
復(fù)制代碼
利用RandomAccessFile實(shí)現(xiàn)文件的多線程下載,即多線程下載一個(gè)文件時(shí),將文件分成幾塊,每塊用不同的線程進(jìn)行下載。下面是一個(gè)利用多線程在寫文件時(shí)的例子,其中預(yù)先分配文件所需要的空間,然后在所分配的空間中進(jìn)行分塊,然后寫入:
  1. import java.io.FileNotFoundException;
  2. import java.io.IOException;
  3. import java.io.RandomAccessFile;

  4. /**
  5. * 測(cè)試?yán)枚嗑程進(jìn)行文件的寫操作
  6. */
  7. public class Test {

  8.         public static void main(String[] args) throws Exception {
  9.                 // 預(yù)分配文件所占的磁盤空間,磁盤中會(huì)創(chuàng)建一個(gè)指定大小的文件
  10.                 RandomAccessFile raf = new RandomAccessFile("D://abc.txt", "rw");
  11.                 raf.setLength(1024*1024); // 預(yù)分配 1M 的文件空間
  12.                 raf.close();
  13.                
  14.                 // 所要寫入的文件內(nèi)容
  15.                 String s1 = "第一個(gè)字符串";
  16.                 String s2 = "第二個(gè)字符串";
  17.                 String s3 = "第三個(gè)字符串";
  18.                 String s4 = "第四個(gè)字符串";
  19.                 String s5 = "第五個(gè)字符串";
  20.                
  21.                 // 利用多線程同時(shí)寫入一個(gè)文件
  22.                 new FileWriteThread(1024*1,s1.getBytes()).start(); // 從文件的1024字節(jié)之后開始寫入數(shù)據(jù)
  23.                 new FileWriteThread(1024*2,s2.getBytes()).start(); // 從文件的2048字節(jié)之后開始寫入數(shù)據(jù)
  24.                 new FileWriteThread(1024*3,s3.getBytes()).start(); // 從文件的3072字節(jié)之后開始寫入數(shù)據(jù)
  25.                 new FileWriteThread(1024*4,s4.getBytes()).start(); // 從文件的4096字節(jié)之后開始寫入數(shù)據(jù)
  26.                 new FileWriteThread(1024*5,s5.getBytes()).start(); // 從文件的5120字節(jié)之后開始寫入數(shù)據(jù)
  27.         }
  28.        
  29.         // 利用線程在文件的指定位置寫入指定數(shù)據(jù)
  30.         static class FileWriteThread extends Thread{
  31.                 private int skip;
  32.                 private byte[] content;
  33.                
  34.                 public FileWriteThread(int skip,byte[] content){
  35.                         this.skip = skip;
  36.                         this.content = content;
  37.                 }
  38.                
  39.                 public void run(){
  40.                         RandomAccessFile raf = null;
  41.                         try {
  42.                                 raf = new RandomAccessFile("D://abc.txt", "rw");
  43.                                 raf.seek(skip);
  44.                                 raf.write(content);
  45.                         } catch (FileNotFoundException e) {
  46.                                 e.printStackTrace();
  47.                         } catch (IOException e) {
  48.                                 // TODO Auto-generated catch block
  49.                                 e.printStackTrace();
  50.                         } finally {
  51.                                 try {
  52.                                         raf.close();
  53.                                 } catch (Exception e) {
  54.                                 }
  55.                         }
  56.                 }
  57.         }

  58. }
復(fù)制代碼
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP