zoukankan      html  css  js  c++  java
  • Java基础(八)——IO流4_随机访问文件流 Craftsman

    一、随机访问文件流

    1、介绍

      RandomAccessFile既可以作为一个输入流,又可以作为一个输出流。作为输出流时,写出到的文件如果不存在,则在执行过程中自动创建。若存在,则会对原有文件内容进行覆盖,默认情况下,从头覆盖。注意,不会覆盖掉整个文件内容。
      创建 RandomAccessFile 类实例需要指定一个 mode 参数,该参数指定它的访问模式:

      r:以只读方式打开。
      rw:打开以便读取和写入。
      rwd:打开以便读取和写入;同步文件内容的更新。
      rws:打开以便读取和 写入;同步文件内容和元数据的更新。

      如果模式为 r,则不会创建文件,而是去读取一个已经存在的文件,如果读取的文件不存在则会出现异常。
      如果模式为 rw 读写,若文件不存在则会创建文件,若存在则不会创建。

    2、RandomAccessFile

      代码示例:复制图片

     1 public class Main {
     2     public static void main(String[] args) {
     3         try (RandomAccessFile raf1 = new RandomAccessFile(new File("F:\\hello.png"), "r");
     4              RandomAccessFile raf2 = new RandomAccessFile(new File("F:\\hello_1.png"), "rw");) {
     5 
     6             byte[] buffer = new byte[1024];
     7             int len;
     8 
     9             while ((len = raf1.read(buffer)) != -1) {
    10                 raf2.write(buffer, 0, len);
    11             }
    12         } catch (Exception e) {
    13         }
    14     }
    15 }

      代码示例:随机写入文件

     1 // 文件:F:\\hello.txt
     2 // 内容:abcdefgh
     3 public class Main {
     4     public static void main(String[] args) {
     5 
     6         File file = new File("F:\\hello.txt");
     7         try (RandomAccessFile raf = new RandomAccessFile(file, "rw");) {
     8 
     9             // raf1.seek(file.length()); // 可实现在文件末尾追加
    10 
    11             // 将指针调到角标为3的位置
    12             raf.seek(3);
    13             raf.write("xyz".getBytes());
    14 
    15         } catch (Exception e) {
    16         }
    17     }
    18 }
    19 
    20 // 结果
    21 // abcxyzgh

      代码示例:实现数据插入的效果

     1 // 文件:F:\\hello.txt
     2 // 内容:
     3 abcdefghi
     4 jkl
     5 mn
     6 public class Main {
     7     public static void main(String[] args) {
     8         File file = new File("F:\\hello.txt");
     9 
    10         try (RandomAccessFile raf = new RandomAccessFile(file, "rw");) {
    11             // 1.将要插入的位置后面的数据保存起来
    12             raf.seek(3);
    13             StringBuilder builder = new StringBuilder((int) file.length());
    14 
    15             // 2.将读到的数据保存在 builder 中
    16             byte[] buffer = new byte[1024];
    17             int len;
    18             while ((len = raf.read(buffer)) != -1) {
    19                 builder.append(new String(buffer, 0, len));
    20             }
    21 
    22             // 3.调回指针,插入数据 “xyz”
    23             raf.seek(3);
    24             raf.write("xyz".getBytes());
    25 
    26             // 4.将 builder 中的数据追加到文件中
    27             raf.write(builder.toString().getBytes());
    28         } catch (Exception e) {
    29         }
    30     }
    31 }
    32 
    33 // 结果
    34 abcxyzdefghi
    35 jkl
    36 mn

      很显然,这种方式,对于文本文件很大的情况,且在前面的位置做插入,很不友好。

    3、应用

      可以用 RandomAccessFile 这个类,来实现一个多线程断点下载的功能,用过下载工具的朋友们都知道,下载前会建立两个临时文件,一个是与被下载文件大小相同的空文件,另一个是记录文件指针位置,每次暂停的时候,都会保存上一次的指针,然后断点下载的时候,会继续从上一次的地方下载,从而实现断点下载或上传的功能。

    作者:Craftsman-L

    本博客所有文章仅用于学习、研究和交流目的,版权归作者所有,欢迎非商业性质转载。

    如果本篇博客给您带来帮助,请作者喝杯咖啡吧!点击下面打赏,您的支持是我最大的动力!

  • 相关阅读:
    mysql索引
    springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
    java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
    java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
    activiti工作流的web流程设计器整合视频教程 SSM和独立部署
    .Net Core中的ObjectPool
    文件操作、流相关类梳理
    .Net Core中的配置文件源码解析
    .Net Core中依赖注入服务使用总结
    消息中间件RabbitMQ(一)
  • 原文地址:https://www.cnblogs.com/originator/p/15736963.html
Copyright © 2011-2022 走看看