zoukankan      html  css  js  c++  java
  • java io系列26之 RandomAccessFile


    本文主要介绍 RandomAccessFile。

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/io_26.html

    更多内容请参考:java io系列01之 "目录"

    RandomAccessFile

    RandomAccessFile 是随机访问文件(包括读/写)的类。它支持对文件随机访问的读取和写入,即我们可以从指定的位置读取/写入文件数据。
    需要注意的是,RandomAccessFile 虽然属于java.io包,但它不是InputStream或者OutputStream的子类;它也不同于FileInputStream和FileOutputStream。 FileInputStream 只能对文件进行读操作,而FileOutputStream 只能对文件进行写操作;但是,RandomAccessFile 同时支持文件的读和写,并且它支持随机访问。

    RandomAccessFile 函数列表

    RandomAccessFile(File file, String mode)
    RandomAccessFile(String fileName, String mode)
    
    void     close()
    synchronized final FileChannel     getChannel()
    final FileDescriptor     getFD()
    long     getFilePointer()
    long     length()
    int     read(byte[] buffer, int byteOffset, int byteCount)
    int     read(byte[] buffer)
    int     read()
    final boolean     readBoolean()
    final byte     readByte()
    final char     readChar()
    final double     readDouble()
    final float     readFloat()
    final void     readFully(byte[] dst)
    final void     readFully(byte[] dst, int offset, int byteCount)
    final int     readInt()
    final String     readLine()
    final long     readLong()
    final short     readShort()
    final String     readUTF()
    final int     readUnsignedByte()
    final int     readUnsignedShort()
    void     seek(long offset)
    void     setLength(long newLength)
    int     skipBytes(int count)
    void     write(int oneByte)
    void     write(byte[] buffer, int byteOffset, int byteCount)
    void     write(byte[] buffer)
    final void     writeBoolean(boolean val)
    final void     writeByte(int val)
    final void     writeBytes(String str)
    final void     writeChar(int val)
    final void     writeChars(String str)
    final void     writeDouble(double val)
    final void     writeFloat(float val)
    final void     writeInt(int val)
    final void     writeLong(long val)
    final void     writeShort(int val)
    final void     writeUTF(String str)

    1. RandomAccessFile 模式说明

    RandomAccessFile共有4种模式:"r", "rw", "rws"和"rwd"。

    "r"    以只读方式打开。调用结果对象的任何 write 方法都将导致抛出 IOException。  
    "rw"   打开以便读取和写入。
    "rws"  打开以便读取和写入。相对于 "rw","rws" 还要求对“文件的内容”或“元数据”的每个更新都同步写入到基础存储设备。  
    "rwd"  打开以便读取和写入,相对于 "rw","rwd" 还要求对“文件的内容”的每个更新都同步写入到基础存储设备。  

    说明
    (01) 什么是“元数据”,即metadata?
    英文解释如下:

    The definition of metadata is "data about other data." With a file system, the data is contained in its files and directories, and the metadata tracks information about each of these objects: Is it a regular file, a directory, or a link? What is its size, creation date, last modified date, file owner, group owner, and access permissions?

    大致意思是:
    metadata是“关于数据的数据”。在文件系统中,数据被包含在文件和文件夹中;metadata信息包括:“数据是一个文件,一个目录还是一个链接”,“数据的创建时间(简称ctime)”,“最后一次修改时间(简称mtime)”,“数据拥有者”,“数据拥有群组”,“访问权限”等等。

    (02) "rw", "rws", "rwd" 的区别。
    当操作的文件是存储在本地的基础存储设备上时(如硬盘, NandFlash等),"rws" 或 "rwd", "rw" 才有区别。
    当模式是 "rws" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]” 或 “修改文件元数据(如文件的mtime)”时,都会将这些改变同步到基础存储设备上。
    当模式是 "rwd" 并且 操作的是基础存储设备上的文件;那么,每次“更改文件内容[如write()写入数据]”时,都会将这些改变同步到基础存储设备上。
    当模式是 "rw" 并且 操作的是基础存储设备上的文件;那么,关闭文件时,会将“文件内容的修改”同步到基础存储设备上。至于,“更改文件内容”时,是否会立即同步,取决于系统底层实现。

    2. 演示程序

    源码如下

      1 import java.io.File;
      2 import java.io.FileDescriptor;
      3 import java.io.FileInputStream;
      4 import java.io.FileOutputStream;
      5 import java.io.BufferedInputStream;
      6 import java.io.BufferedOutputStream;
      7 import java.io.PrintStream;;
      8 import java.io.RandomAccessFile;
      9 import java.io.IOException;
     10 
     11 /**
     12  * RandomAccessFile 测试程序
     13  *
     14  * 运行结果(输出如下):
     15  * c1=a
     16  * c2=b
     17  * buf=9876543210
     18  * 
     19  * 此外,
     20  * (01) 在源文件所在目录生成了file.txt。
     21  * (02) 注意RandomAccessFile写入boolean, byte, char, int,所占的字符个数。
     22  *
     23  * @author skywang
     24  */
     25 public class RandomAccessFileTest {
     26 
     27     private static final String FileName = "file.txt";
     28 
     29     public static void main(String[] args) {
     30         // 若文件“file.txt”存在,则删除该文件。
     31         File file = new File(FileName);
     32         if (file.exists())
     33             file.delete();
     34 
     35         testCreateWrite();
     36         testAppendWrite();
     37         testRead();
     38     }
     39 
     40     /**
     41      * 若“file.txt”不存在的话,则新建文件,并向文件中写入内容
     42      */
     43     private static void testCreateWrite() {
     44         try {
     45             // 创建文件“file.txt”对应File对象
     46             File file = new File(FileName);
     47             // 创建文件“file.txt”对应的RandomAccessFile对象
     48             RandomAccessFile raf = new RandomAccessFile(file, "rw");
     49 
     50             // 向“文件中”写入26个字母+回车
     51             raf.writeChars("abcdefghijklmnopqrstuvwxyz
    ");
     52             // 向“文件中”写入"9876543210"+回车
     53             raf.writeChars("9876543210
    ");
     54 
     55             raf.close();
     56         } catch(IOException e) {
     57             e.printStackTrace();
     58         }
     59     }
     60 
     61     /**
     62      * 向文件末尾追加内容
     63      */
     64     private static void testAppendWrite() {
     65         try {
     66             // 创建文件“file.txt”对应File对象
     67             File file = new File(FileName);
     68             // 创建文件“file.txt”对应的RandomAccessFile对象
     69             RandomAccessFile raf = new RandomAccessFile(file, "rw");
     70 
     71             // 获取文件长度
     72             long fileLen = raf.length();
     73             // 将位置定位到“文件末尾”
     74             raf.seek(fileLen);
     75 
     76             // 以下向raf文件中写数据  
     77             raf.writeBoolean(true); // 占1个字节  
     78             raf.writeByte(0x41);    // 占1个字节  
     79             raf.writeChar('a');     // 占2个字节  
     80             raf.writeShort(0x3c3c); // 占2个字节  
     81             raf.writeInt(0x75);     // 占4个字节  
     82             raf.writeLong(0x1234567890123456L); // 占8个字节  
     83             raf.writeFloat(4.7f);  // 占4个字节  
     84             raf.writeDouble(8.256);// 占8个字节  
     85             raf.writeUTF("UTF严"); // UTF-8格式写入
     86             raf.writeChar('
    ');   // 占2个字符。“换行符”
     87 
     88             raf.close();
     89         } catch(IOException e) {
     90             e.printStackTrace();
     91         }
     92     }
     93 
     94     /**
     95      * 通过RandomAccessFile读取文件
     96      */
     97     private static void testRead() {
     98         try {
     99             // 创建文件“file.txt”对应File对象
    100             File file = new File(FileName);
    101             // 创建文件“file.txt”对应的RandomAccessFile对象,以只读方式打开
    102             RandomAccessFile raf = new RandomAccessFile(file, "r");
    103 
    104             // 读取一个字符
    105             char c1 = raf.readChar();
    106             System.out.println("c1="+c1);
    107             // 读取一个字符
    108             char c2 = raf.readChar();
    109             System.out.println("c2="+c2);
    110 
    111             // 跳过54个字节。
    112             raf.seek(54);
    113 
    114             // 测试read(byte[] buffer, int byteOffset, int byteCount)
    115             byte[] buf = new byte[20];
    116             raf.read(buf, 0, buf.length);
    117             System.out.println("buf="+(new String(buf)));
    118 
    119             raf.close();
    120         } catch(IOException e) {
    121             e.printStackTrace();
    122         }
    123     }
    124 }

    运行结果
    c1=a
    c2=b
    buf=9876543210
    结果说明
    程序会在源文件所在目录生成file.txt;file.txt的内容如下:

    file.txt对应的16进制内容如下:

     

  • 相关阅读:
    模块
    javacript一键换肤
    ajax请求
    jquery获取元素的方法
    ajax请求里的contentType: "application/json"作用
    Underscore.js 入门-常用方法介绍
    .NET Core调用WCF的最佳实践
    证伪主义——科学与伪科学的量尺
    高效的筒仓
    此时此刻,一个项目正在走向失败
  • 原文地址:https://www.cnblogs.com/skywang12345/p/io_26.html
Copyright © 2011-2022 走看看