您当前的位置: 首页 > 

梁云亮

暂无认证

  • 2浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

RandomAccessFile 随机读写文件

梁云亮 发布时间:2022-03-26 14:03:43 ,浏览量:2

简介

RandomAccessFile既可以读取文件内容,也可以向文件输出数据。同时,RandomAccessFile支持“随机访问”的方式,程序快可以直接跳转到文件的任意地方来读写数据。

由于RandomAccessFile可以自由访问文件的任意位置,所以如果需要访问文件的部分内容,而不是把文件从头读到尾,使用RandomAccessFile将是更好的选择。

与OutputStream、Writer等输出流不同的是,RandomAccessFile允许自由定义文件记录指针,RandomAccessFile可以不从开始的地方开始输出,因此RandomAccessFile可以向已存在的文件后追加内容。如果程序需要向已存在的文件后追加内容,则应该使用RandomAccessFile。

RandomAccessFile的方法虽然多,但它有一个最大的局限,就是只能读写文件,不能读写其他IO节点。

RandomAccessFile的一个重要使用场景就是网络请求中的多线程下载及断点续传。

RandomAccessFile类有两个构造函数,其实这两个构造函数基本相同,只不过是指定文件的形式不同:一个需要使用String参数来指定文件名,一个使用File参数来指定文件本身。除此之外,创建RandomAccessFile对象时还需要指定一个mode参数,该参数指定RandomAccessFile的访问模式,一共有4种模式。

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

注意:当RandomAccessFile向指定文件中插入内容时,将会覆盖掉原有内容。如果不想覆盖掉,则需要将原有内容先读取出来,然后先把插入内容插入后再把原有内容追加到插入内容后。

示例
public class DemoTest{
    /**
     * 在目标文件的任意位置插入内容
     * 1、将插入点之后的内容写到临时文件中
     * 2、将待插入的内容插入到插入点位置
     * 3、将临时文件中的内容追加到目标文件的结尾
     *
     * @param fileName 待插入内容的内容
     * @param pos      插入位置
     * @param content  插入内容
     * @throws IOException
     */
    public static void fileRandInsert(String fileName, int pos, String content) {
        File file = new File(fileName);
        RandomAccessFile raf = null;
        FileOutputStream fos = null;
        FileInputStream fis = null;
        try {
            raf = new RandomAccessFile(file, "rw");

            //临时文件
            File tmp = File.createTempFile("hahaha", "tmp");
            fos = new FileOutputStream(tmp);
            fis = new FileInputStream(tmp);

            raf.seek(pos);

            int len = -1;
            byte[] buf = new byte[2];
            while ((len = raf.read(buf)) != -1) {
                fos.write(buf, 0, len);
            }
            fos.flush();

            raf.seek(pos);
            //将字符串转换成字节数组
            byte[] bytes = content.getBytes();
            raf.write(bytes);
            //将文件指针定位到追加后的位置
            raf.seek(pos + bytes.length);

            while ((len = fis.read(buf)) != -1) {
                raf.write(buf, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            try {
                if (fis != null) {
                    fis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (fos != null) {
                        fos.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (raf != null) {
                        try {
                            raf.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    public static void main(String[] args) throws Exception {
        int insertPosition = 11;
        String content = "中国人民";
        String fileName = "abcd";

        fileRandInsert(fileName, insertPosition, content);
    }
}

核心方法说明:

  • long getFilePointer( ):返回文件记录指针的当前位置
  • void seek(long pos ):将文件指针定位到pos位置
关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0444s